source: trunk/dasscm/dasscm@ 244

Last change on this file since 244 was 244, checked in by joergs, on Oct 10, 2008 at 4:42:28 PM

change error message

  • Property keyword set to id
  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 23.1 KB
RevLine 
[186]1#!/usr/bin/perl -w
2
3# $Id: dasscm 244 2008-10-10 14:42:28Z joergs $
4
5use strict;
6
[208]7use Env
[235]8 qw($DASSCM_PROD $DASSCM_REPO $USER $DASSCM_USERNAME $DASSCM_USER $DASSCM_PASSWORD $SHELL);
[186]9use Cwd;
[214]10use Getopt::Long;
[186]11use File::Basename;
[209]12use File::Compare;
13use File::Copy;
[237]14use File::Find;
[186]15use File::stat;
16use File::Path;
[214]17use Term::ReadKey;
[239]18
[234]19#use Data::Dumper;
[186]20
[189]21#####################################################################
22#
[186]23# global
[189]24#
[205]25
[215]26# file to store permissions
27my $permissions_file = "/etc/permissions.d/dasscm.permission_backup";
[220]28
[238]29# documentation file (for usage)
30my $doc_file = "/usr/share/doc/packages/dasscm/dasscm_howto.txt";
31
[215]32# configuration file
[205]33my $config_file = "/etc/dasscm.conf";
[234]34my $config = get_config($config_file);
[205]35my $DASSCM_LOCAL_REPOSITORY_BASE;
36my $DASSCM_REPOSITORY_NAME;
37my $DASSCM_SVN_REPOSITORY;
38
[238]39# current directory at program start
40my $StartDirectory = cwd();
41
[205]42my $SVN = "svn ";
43my $svnOptions = "";
44my $svnCheckoutCredentials = "";
45my $svnPasswordCredentials = "";
[238]46my $diff = "diff --exclude .svn ";
[205]47
[196]48# command line options get stored in options hash
[205]49my %options = ();
50
[197]51# subcommand, that gets executed (add, commit, ...)
[196]52my $command;
[186]53
[205]54my $verbose = 0;
55
[189]56#####################################################################
57#
[186]58# util functions
[189]59#
[187]60sub usage()
61{
[205]62 print "usage: dasscm <subcommand> [options] [args]\n";
63 print "\n";
64 print "dasscm is intended to help versioning configuration files\n";
65 print "\n";
66 print "Available subcommands:\n";
[215]67 print " help <subcommand>\n";
[205]68 print " init\n";
69 print " login\n";
[215]70 print " up\n";
71 print " ls\n";
[205]72 print " add <filename>\n";
73 print " commit <filename>\n";
74 print " diff <filename>\n";
[236]75 print " status\n";
[215]76 print " permissions\n";
[205]77 print "\n";
[238]78 print "preparation:\n", " if dasscm is already configured,\n",
[236]79 " use 'dasscm login' and then eg. 'add'.\n",
[220]80 " The environment variables\n", " DASSCM_REPO\n", " DASSCM_PROD\n",
81 " DASSCM_USERNAME\n", " DASSCM_PASSWORD\n",
82 " are evaluated, but set automatically by 'dasscm login'.\n", "\n",
[239]83 " If dasscm is not yet configured, read", " $doc_file\n";
[187]84}
85
[233]86sub warning(@)
87{
88 print "Warning: " . join( "\n ", @_ ) . "\n";
89}
90
91sub error(@)
92{
93 print "Error: " . join( "\n ", @_ ) . "\n";
94}
95
96sub fatalerror(@)
97{
[239]98 error(@_);
99
[233]100 #print "Exiting\n";
[239]101 exit 1;
[233]102}
103
[238]104#
105# reading config file and return key/value pairs as hash
106#
[234]107sub get_config
108{
[239]109 my $file = $_[0];
[234]110
[239]111 if ( !$file ) {
[234]112 fatalerror( "failed to open config file" . $file );
113 }
114
115 my $data = {};
116
117 # try to open config file
118 if ( !open( FH, $file ) ) {
119 fatalerror( "failed to open config file" . $file );
120 } else {
121 while (<FH>) {
122 chomp;
123 if (/^#/) {
124 next;
125 }
126 if ( $_ =~ /=/g ) {
[239]127
[238]128 # splitting in 2 fields at maximum
[234]129 my ( $option, $value ) = split( /=/, $_, 2 );
130 $option =~ s/^\s+//g;
131 $option =~ s/\s+$//g;
132 $option =~ s/\"+//g;
133 $value =~ s/^\s+//g;
134 $value =~ s/\s+$//g;
135 $value =~ s/\"+//g;
136
137 if ( length($option) ) {
138 $data->{$option} = $value;
139 }
140 }
141 }
142 }
143 close(FH);
144
145 return $data;
146}
147
[186]148sub check_env()
149{
[205]150
151 # DASSCM_PROD
152 if ( !$DASSCM_PROD ) {
153 $DASSCM_PROD = "/";
154 }
155
156 if ( !-d $DASSCM_PROD ) {
157 die "DASSCM_PROD ($DASSCM_PROD) is not set to a directory.\n";
158 }
159 if ($verbose) { print "DASSCM_PROD: " . $DASSCM_PROD . "\n"; }
160
161 # DASSCM_REPOSITORY_NAME
[208]162 if ( !$DASSCM_REPOSITORY_NAME ) {
163 die
164 "Variable DASSCM_REPOSITORY_NAME is not defined.\nIt needs to be a unique name.\nNormally the full qualified host name is used.\nUse file $config_file to configure it.\n";
165 }
[205]166
167 # DASSCM_REPO
168 if ( !$DASSCM_REPO ) {
169 if ( $DASSCM_LOCAL_REPOSITORY_BASE && $DASSCM_REPOSITORY_NAME ) {
170 $DASSCM_REPO =
171 $DASSCM_LOCAL_REPOSITORY_BASE . "/" . $DASSCM_REPOSITORY_NAME;
172 } else {
173 die
174 "Envirnonment variable DASSCM_REPO not set.\nSet DASSCM_REPO to the directory of the versioning system checkout for this machine.\n";
175 }
176 }
[215]177 if ($verbose) { print "DASSCM_REPO: " . $DASSCM_REPO . "\n"; }
[205]178
179 #
[239]180 # check if local repository directory exist
[235]181 # (if not creating by init)
[205]182 #
183 if ( $command ne "init" ) {
184 if ( not -d $DASSCM_REPO ) {
185 die
[208]186 "Can't access local repository DASSCM_REPO\n($DASSCM_REPO)\nCheck configuration and execute\n dasscm init\n";
[205]187 }
[208]188
[205]189 #
190 # user settings
191 #
[208]192
[205]193 # DASSCM_USER is legacy. Use DASSCM_USERNAME instead
[208]194 if ( !$DASSCM_USERNAME ) {
195 $DASSCM_USERNAME = $DASSCM_USER;
[205]196 }
197
198 # user root is not allowed for checkins.
199 # if user is root, DASSCM_USER has to be set,
200 # otherwise USER can be used
201 if ( "$USER" eq "root" ) {
[208]202 if ( ( not $DASSCM_USERNAME ) and ( $command ne "login" ) ) {
[244]203 fatalerror( "Envirnonment variable DASSCM_USERNAME not set.", "Set DASSCM_USERNAME to your subversion user account or", "use 'dasscm login'";
[205]204 }
205 $svnOptions .= " --no-auth-cache ";
206 } elsif ( !$DASSCM_USERNAME ) {
207 $DASSCM_USERNAME = $USER;
208 }
209
210 #
211 # password
212 #
[208]213 if ($DASSCM_PASSWORD) {
[205]214 $svnPasswordCredentials = " --password $DASSCM_PASSWORD ";
215 }
216 }
217
218 #$svnOptions .= " --username $DASSCM_USERNAME "
[186]219}
220
221sub check_parameter(@)
222{
223}
224
[238]225#
[239]226# generate from (relative) filename
[238]227# all required file and directory names:
228# $basename, $dirname_prod, $dirname_repo,
229# $filename_prod, $filename_repo
230#
[187]231sub get_filenames(@)
232{
[205]233 my $filename_prod = $_[0];
[237]234
[238]235 # make filename absolut
[205]236 if ( !( $filename_prod =~ m/^\// ) ) {
237 $filename_prod = cwd() . "/" . $filename_prod;
238 }
[187]239
[239]240 if ( not -r $filename_prod ) {
241 fatalerror( $filename_prod . " is not accessable" );
[233]242 }
[205]243
244 # TODO: dirname buggy: eg. "/etc/" is reduced to "/",
245 # "/etc" is used as filename
246 my $dirname_prod = dirname($filename_prod);
[238]247
248 # uses chdir to determine real directory in a unique way
[205]249 chdir $dirname_prod or die $!;
250 $dirname_prod = cwd();
[238]251 chdir $StartDirectory;
252
[205]253 my $basename = basename($filename_prod);
254
[214]255 if ($verbose) {
256 print "dir: " . $dirname_prod . "\n";
257 print "fn: " . $basename . "\n";
258 }
[205]259
260 my $dirname_repo = $DASSCM_REPO . "/" . $dirname_prod;
261 my $filename_repo = "$dirname_repo/$basename";
262
263 return (
264 $basename, $dirname_prod, $dirname_repo,
265 $filename_prod, $filename_repo
266 );
[187]267}
268
[215]269sub generatePermissionList
[209]270{
271
[215]272 # generieren der Zeilen für Permission-Savefile
273 my @files = @_;
274 my @permlist = ();
275 foreach my $file (@files) {
[227]276 $file = "/" . $file;
[239]277 if ( -e $file ) {
278 my $info = stat($file) || die "failed to stat $file: aborting";
279 my $mode = get_type( $info->mode ) & 07777;
[227]280 my $modestring = sprintf( "%04o", $mode );
281 my $uid = $info->uid;
282 my $uidname = getpwuid($uid);
283 my $gid = $info->gid;
284 my $gidname = getgrgid($gid);
285 push(
286 @permlist,
287 sprintf( "%-55s %-17s %4d",
288 $file, "${uidname}:${gidname}", $modestring )
289 );
290 } else {
[239]291 print
292 "failed to get status of $file. It exists in the repository, but not on the system\n";
[227]293 }
[215]294 }
295 return @permlist;
296}
[209]297
[215]298sub get_type
299{
[209]300
[215]301 # Funktion übernommen aus /usr/bin/chkstat
302 my $S_IFLNK = 0120000; # symbolic link
303 my $S_IFREG = 0100000; # regular file
304 my $S_IFDIR = 0040000; # directory
305 my $S_IFCHAR = 0020000; # character device
306 my $S_IFBLK = 0060000; # block device
307 my $S_IFFIFO = 0010000; # fifo
308 my $S_IFSOCK = 0140000; # socket
309 my $S_IFMT = 0170000; # type of file
[209]310
[215]311 my $S_m;
312 if ( ( $_[0] & $S_IFMT ) == $S_IFLNK ) { $S_m = $_[0] - $S_IFLNK; }
313 elsif ( ( $_[0] & $S_IFMT ) == $S_IFREG ) { $S_m = $_[0] - $S_IFREG; }
314 elsif ( ( $_[0] & $S_IFMT ) == $S_IFDIR ) { $S_m = $_[0] - $S_IFDIR; }
315 elsif ( ( $_[0] & $S_IFMT ) == $S_IFCHAR ) { $S_m = $_[0] - $S_IFCHAR; }
316 elsif ( ( $_[0] & $S_IFMT ) == $S_IFBLK ) { $S_m = $_[0] - $S_IFBLK; }
317 elsif ( ( $_[0] & $S_IFMT ) == $S_IFFIFO ) { $S_m = $_[0] - $S_IFFIFO; }
318 elsif ( ( $_[0] & $S_IFMT ) == $S_IFSOCK ) { $S_m = $_[0] - $S_IFSOCK; }
319 $S_m;
[209]320}
321
[186]322sub run_command
323{
[205]324 my $command = shift;
[186]325
[205]326 #print "executing command: " . $command . "\n";
[186]327
[205]328 open( RESULT, $command . ' 2>&1 |' );
329 my @result = <RESULT>;
330 close(RESULT);
331 my $retcode = $? >> 8;
[186]332
[205]333 #print @result;
334 #if( $retcode ) { print "return code: " . $retcode . "\n"; }
[186]335
[205]336 return ( $retcode, @result );
[186]337}
338
[205]339sub run_interactive
340{
[186]341
[208]342 if ($verbose) {
[205]343 print "run_interactive:" . join( " ", @_ ) . "\n";
344 }
[196]345
[205]346 system(@_);
347 if ( $? == -1 ) {
348 printf "failed to execute: $!\n";
349 } elsif ( $? & 127 ) {
350 printf "child died with signal %d, %s coredump\n", ( $? & 127 ),
351 ( $? & 128 ) ? 'with' : 'without';
352 } elsif ( $? >> 8 != 0 ) {
353 printf "child exited with value %d\n", $? >> 8;
354 }
355 return ( $? >> 8 );
356}
357
358sub svn_check_credentials( $$ )
[196]359{
[205]360 my $username = shift;
361 my $password = shift;
362
[220]363 print "checking credentials ... ";
364
[239]365 if ( !$username ) {
366 fatalerror("no username given");
[238]367 }
368
[239]369 if ( !$password ) {
370 fatalerror("no password given");
[238]371 }
372
[220]373 # Options for "svn info" are not supported by subversion 1.0.0 (SLES9),
374 # therefore switching to "svn status"
375 # ( my $rc_update, my @result ) =
376 # run_command(
377 # "$SVN info --non-interactive --no-auth-cache --username $username --password $password $DASSCM_SVN_REPOSITORY"
378 # );
379 #print @result;
380
[205]381 ( my $rc_update, my @result ) =
382 run_command(
[220]383 "$SVN ls --non-interactive --no-auth-cache --username $username --password $password $DASSCM_SVN_REPOSITORY"
[205]384 );
385
386 if ( $rc_update != 0 ) {
[238]387 print "\n", @result;
388 fatalerror();
[205]389 }
390
[196]391}
392
[205]393sub svn_update( ;$ )
394{
395 my $update_path = shift || $DASSCM_REPO;
396 ( my $rc_update, my @result ) =
[220]397 run_command(
398 "$SVN update --non-interactive $svnCheckoutCredentials $update_path");
[215]399 print @result;
[205]400 if ( $rc_update != 0 ) {
[238]401 fatalerror();
[205]402 }
[215]403}
[196]404
[215]405sub svn_getStoredFiles( ;$ )
406{
[220]407
[215]408 # TODO: get_filenames?
409 #my $rel_path = shift || "";
410 #my $path = "${DASSCM_REPO}/${rel_path}";
411 my $path = ${DASSCM_REPO};
[220]412
[218]413 # svn ls -R is better, but much, much slower
414 # ( my $rc, my @result ) = run_command("$SVN ls --recursive $svnCheckoutCredentials $path");
[220]415 ( my $rc, my @result ) =
416 run_command(
417 "cd $path && find | grep -v '/.svn' | sed -e 's/\.\\///' | grep -v '^\$'"
418 );
[215]419 if ( $rc != 0 ) {
420 print @result;
[238]421 fatalerror;
[215]422 }
423 chomp(@result);
424 return @result;
[205]425}
426
[238]427#
428# from an array of files/dirs,
429# generates list of files
430# sorted by type
431#
[237]432sub get_files( @ )
433{
434 my @files = ();
435 my @links = ();
436 my @dirs = ();
437 my @others = ();
438
[239]439 if (@_) {
440 find(
441 {
442 wanted => sub {
443 my $fullname = cwd() . "/" . $_;
444 if ( -l $_ ) {
445
446 # soft link
447 # important: check for links first
448 # to exclude them from further checks
449 push( @links, $fullname );
450 } elsif ( -d $_ ) {
451 push( @dirs, $fullname );
452 } elsif ( -f $_ ) {
453
454 # regular file
455 push( @files, $fullname );
456 } else {
457 push( @others, $fullname );
458 }
459 }
460 },
461 @_
462 );
[237]463 }
464
[239]465 # don't rely on others.
[237]466 # If more specific file types are needed,
467 # they will be added
468 return {
[239]469 files => \@files,
470 links => \@links,
471 dirs => \@dirs,
472 others => \@others
473 };
[237]474}
475
[189]476#####################################################################
477#
[186]478# functions
479
480sub help(;@)
481{
[205]482 if ( @_ == 0 ) {
483 usage();
484 } else {
485 print "help for @_: ...\n";
[214]486 usage();
[205]487 }
[186]488}
489
[203]490sub login(@)
491{
[205]492 check_parameter( @_, 1 );
493 check_env();
[203]494
[235]495 my $input_username = $_[0];
[214]496
497 if ( not $input_username ) {
498 my $output_username = "";
499 if ($DASSCM_USERNAME) {
500 $output_username = " ($DASSCM_USERNAME)";
501 }
502
503 print "Enter DASSCM user name", $output_username, ": ";
504 $input_username = <STDIN>;
505 chomp($input_username);
[205]506 }
[203]507
[205]508 # hidden password input
509 print "Enter DASSCM user password: ";
510 ReadMode('noecho');
511 my $input_password = <STDIN>;
512 ReadMode('normal');
513 chomp($input_password);
[220]514 print "\n";
[203]515
[239]516 svn_check_credentials( $input_username || $DASSCM_USERNAME,
517 $input_password );
[205]518
519 #
520 # set environment variables
521 #
522 $ENV{'DASSCM_USERNAME'} = $input_username;
523 $ENV{'DASSCM_PASSWORD'} = $input_password;
524
[209]525 print "subversion access okay\n\n", "DASSCM_USERNAME: $input_username\n",
526 "DASSCM_PASSWORD: (hidden)\n", "DASSCM_PROD: $DASSCM_PROD\n",
527 "DASSCM_REPO: $DASSCM_REPO\n",
528 "Server Repository: $DASSCM_SVN_REPOSITORY\n", "\n", "[dasscm shell]\n\n";
[205]529
[235]530 my $shell = $SHELL || "bash";
531 exec($shell) or die "failed to start new shell";
[203]532}
533
[205]534sub init(@)
535{
536 check_parameter( @_, 1 );
537 check_env();
538
[235]539 # don't do repository creation (svn mkdir) here,
540 # because then their must be a lot of prior checks
541
[205]542 # update complete repository
[216]543 # and create permission file
[208]544 my $retcode =
545 run_interactive(
[225]546 "cd $DASSCM_LOCAL_REPOSITORY_BASE; $SVN checkout $svnCheckoutCredentials $svnOptions $DASSCM_SVN_REPOSITORY; touch $permissions_file"
[208]547 );
[205]548}
549
[215]550sub ls(@)
[186]551{
[205]552 check_parameter( @_, 1 );
553 check_env();
[186]554
[215]555 my @files = svn_getStoredFiles(@_);
556
557 print join( "\n", @files );
558 print "\n";
559}
560
561sub update(@)
562{
563 check_parameter( @_, 1 );
564 check_env();
565
566 #
567 # update local repository
568 #
569 svn_update();
570}
571
[237]572#
573# helper function for "add" command
574#
[215]575sub add_helper(@)
576{
[205]577 (
578 my $basename,
579 my $dirname_prod,
580 my $dirname_repo,
581 my $filename_prod,
582 my $filename_repo
583 )
584 = get_filenames( $_[0] );
[186]585
[205]586 if ( $command eq "add" ) {
587 mkpath($dirname_repo);
588 }
[186]589
[238]590 # TODO: are permissions also copied?
[239]591 copy( $filename_prod, $filename_repo )
592 or error "failed to copy $filename_prod to repository: $!";
[205]593
594 if ( $command eq "add" ) {
595
596 # already checked in?
[238]597 chdir $DASSCM_REPO;
[205]598
599 # also add the path to filename.
600 for my $dir ( split( '/', $dirname_prod ) ) {
601 if ($dir) {
[239]602 my ( $rc, @out ) =
603 run_command( "$SVN add --non-recursive \"" . $dir . "\"" );
604 if ( $rc > 0 ) {
[226]605 print join( "\n", @out );
[239]606 }
[205]607 chdir $dir;
608 }
609 }
[239]610 my ( $rc, @out ) = run_command( "$SVN add \"" . $basename . "\"" );
611 if ( $rc > 0 ) {
[226]612 print join( "\n", @out );
[239]613 }
[238]614 chdir $StartDirectory;
[205]615 }
[215]616}
[205]617
[215]618#
619# add (is used for command add and commit)
620#
621sub add(@)
622{
623 check_parameter( @_, 1 );
624 check_env();
625
626 #
627 # update local repository
628 #
629 svn_update();
630
[237]631 # get all regular files and links
[239]632 my $href_files = get_files(@_);
[220]633
[237]634 #print Dumper( $href_files );
635
[239]636 my @files = @{ $href_files->{files} };
637 my @links = @{ $href_files->{links} };
[237]638
[239]639 if (@files) {
[237]640 my $number = $#files + 1;
641 print "files to check-in ($number): \n";
642 print join( "\n", @files );
643 print "\n";
644 }
645
[239]646 if (@links) {
[237]647 my $number = $#links + 1;
648 print "\n";
649 print "ignoring links ($number):\n";
650 print join( "\n", @links );
651 print "\n";
652 }
653
[238]654 # TODO: confirm
655
[237]656 # copy files one by one to local repository
657 for my $file (@files) {
[239]658
[233]659 # add file
[239]660 add_helper($file);
[233]661 }
662
[215]663 # create new permissions file
664 permissions();
[220]665
[215]666 # add permissions file
[220]667 add_helper($permissions_file);
[215]668
[205]669 if ( $options{'message'} ) {
670 $svnOptions .= " --message \"$options{'message'}\" ";
671 }
672
[239]673 # commit calls $EDITOR.
[237]674 # use "interactive" here, to display output
[215]675 my $retcode =
[205]676 run_interactive(
[208]677 "$SVN commit $svnOptions --username $DASSCM_USERNAME $svnPasswordCredentials $DASSCM_REPO"
678 );
[205]679
[215]680 #print $filename_prod. "\n";
681 #print $dirname_repo. "\n";
[186]682}
683
[193]684sub blame(@)
685{
[205]686 check_parameter( @_, 1 );
687 check_env();
[193]688
[205]689 (
690 my $basename,
691 my $dirname_prod,
692 my $dirname_repo,
693 my $filename_prod,
694 my $filename_repo
695 )
696 = get_filenames( $_[0] );
697
698 my $retcode = run_interactive("$SVN blame $svnOptions $filename_repo");
[193]699}
700
[187]701sub diff(@)
702{
[205]703 check_parameter( @_, 1 );
704 check_env();
[187]705
[205]706 (
707 my $basename,
708 my $dirname_prod,
709 my $dirname_repo,
710 my $filename_prod,
711 my $filename_repo
712 )
713 = get_filenames( $_[0] );
714
715 #print "$basename,$dirname_prod,$dirname_repo\n";
716
717 ( my $rc_update, my @result ) = run_command("$SVN update $filename_repo");
718 if ( $rc_update != 0 ) {
719 print @result;
720 die;
721 }
722
[238]723 ( my $rc_diff, my @diff_result ) =
[239]724 run_command( $diff . " $filename_repo $filename_prod" );
[238]725
726 print @diff_result;
[187]727}
728
[209]729sub status(@)
730{
731 check_parameter( @_, 1 );
732 check_env();
733
734 #
735 # update local repository
736 #
737 svn_update();
738
739 # TODO: start at subdirectories ?
[220]740 my $dir = $DASSCM_REPO;
[215]741 my @files = svn_getStoredFiles($dir);
[209]742
743 # Liste der geänderten Files ausgeben, falls nicht leer
[215]744 if (@files) {
[209]745
[215]746 # stores result from status (cvscheck)
747 my %removedfiles = ();
748 my %changedfiles = ();
749
750 foreach my $file (@files) {
751
752 my $realfile = "/" . $file;
753 my $cvsworkfile = "${DASSCM_REPO}/${file}";
754
755 if ( -d $realfile ) {
756
757 # directory. do nothing
758 } elsif ( !-r $realfile ) {
759 $removedfiles{"$realfile"} = $cvsworkfile;
760 } else {
761 ( -r "$cvsworkfile" )
762 || die("Fehler: $cvsworkfile ist nicht lesbar");
763 if ( compare( $cvsworkfile, $realfile ) != 0 ) {
764 $changedfiles{"$realfile"} = $cvsworkfile;
765 }
766 }
767 }
768
769 if (%removedfiles) {
770 print "deleted files (found in repository, but not in system):\n";
771 foreach my $key ( values %removedfiles ) {
[209]772 print "$key\n";
773 }
774 print "\n";
775 }
776
[215]777 if (%changedfiles) {
[209]778 print "modified files:\n";
[215]779 foreach my $key ( keys %changedfiles ) {
[209]780 print "$key\n";
781 }
782 }
783 } else {
[215]784 print "no modified files found in $dir\n";
[209]785 }
[215]786
[209]787 print "\n";
[215]788}
[209]789
[215]790sub permissions(@)
791{
792 check_parameter( @_, 1 );
793 check_env();
794
795 #
796 # update local repository
797 #
798 #svn_update();
799
800 # TODO: start at subdirectories ?
[220]801 my $dir = $DASSCM_REPO;
[215]802 my @files = svn_getStoredFiles($dir);
803
804 if (@files) {
805
806 # generieren der Permissions
807 my @permissions = generatePermissionList(@files);
808 my $OUTFILE;
809 my $tofile = 0; # Status für schreiben in File
[220]810
[215]811 if ( -w dirname($permissions_file) ) {
812
813 # Verzeichnis existiert => schreiben
814 print "storing permissions in file $permissions_file\n";
815 open( OUTFILE, ">$permissions_file" )
[216]816 || die("failed to write to $permissions_file: $!");
[215]817 $tofile = 1; # Merken, daß in File geschrieben wird
818 print OUTFILE "#\n";
819 print OUTFILE "# created by dasscm permissions\n";
[220]820 print OUTFILE
821 "# It is intended to be used for restoring permissions\n";
[215]822 } else {
823
824 # Pfad für Sicherungsdatei existiert nicht => schreiben auf stdout
825 # Alias Filehandle für stdout erzeugen
826 *OUTFILE = *STDOUT;
827 }
828 foreach my $line (@permissions) {
829 print OUTFILE "$line\n";
830 }
831
[220]832 if ($tofile) {
[215]833 close(OUTFILE);
834 }
835 }
[209]836}
837
[189]838#####################################################################
839#
[186]840# main
[189]841#
[186]842
843my $number_arguments = @ARGV;
844
[205]845if ( $number_arguments > 0 ) {
[186]846
[205]847 # get subcommand and remove it from @ARGV
848 $command = $ARGV[0];
849 shift @ARGV;
[196]850
[205]851 $DASSCM_LOCAL_REPOSITORY_BASE = $config->{'DASSCM_LOCAL_REPOSITORY_BASE'};
852 $DASSCM_REPOSITORY_NAME = $config->{'DASSCM_REPOSITORY_NAME'};
[196]853
[205]854 # TODO: check variables
855 $DASSCM_SVN_REPOSITORY =
856 $config->{'DASSCM_SVN_REPOSITORY_BASE'} . "/" . $DASSCM_REPOSITORY_NAME;
857
858 my $DASSCM_CHECKOUT_USERNAME = $config->{'DASSCM_CHECKOUT_USERNAME'};
859 my $DASSCM_CHECKOUT_PASSWORD = $config->{'DASSCM_CHECKOUT_PASSWORD'};
860
861 #
862 # if a user is given by dasscm configuration file, we use it.
863 # Otherwise we expect that read-only account is configured
864 # as local subversion configuration.
865 # If this is also not the case,
866 # user is required to type username and password.
867 # This will be stored as local subversion configuration thereafter.
868 #
869 if ( $DASSCM_CHECKOUT_USERNAME && $DASSCM_CHECKOUT_PASSWORD ) {
870 $svnCheckoutCredentials =
871 " --username $DASSCM_CHECKOUT_USERNAME --password $DASSCM_CHECKOUT_PASSWORD ";
872 }
873
874 # get command line options and store them in options hash
[214]875 my $result = GetOptions( \%options, 'verbose', 'message=s' );
[205]876
877 # print options
878 foreach my $option ( keys %options ) {
[215]879 print "${option}: $options{$option}\n";
[205]880 }
881
[214]882 # set verbose to command line option
883 $verbose = $options{'verbose'};
884
885 #
886 # action accordinly to command are taken
887 # $command is rewritten in standard format,
888 # so we can test for it later on more simply
889 #
[205]890 $_ = $command;
891 if (m/help/i) {
892 help(@ARGV);
893 } elsif (m/login/i) {
[208]894 $command = "login";
[205]895 login(@ARGV);
896 } elsif (m/init/i) {
[208]897 $command = "init";
[205]898 init(@ARGV);
[215]899 } elsif (m/ls/i) {
900 $command = "ls";
901 ls(@ARGV);
[235]902 } elsif ( (m/update/i) || (m/up/i) ) {
[215]903 $command = "update";
904 update(@ARGV);
[205]905 } elsif (m/add/i) {
906 $command = "add";
907 add(@ARGV);
908 } elsif (m/commit/i) {
909 $command = "commit";
910 add(@ARGV);
911 } elsif (m/blame/i) {
[208]912 $command = "blame";
[205]913 blame(@ARGV);
914 } elsif (m/diff/i) {
[208]915 $command = "diff";
[205]916 diff(@ARGV);
[235]917 } elsif ( (m/status/i) || (m/st/i) ) {
[209]918 $command = "status";
919 status(@ARGV);
[215]920 } elsif (m/permissions/i) {
921 $command = "permissions";
922 permissions(@ARGV);
[205]923 } else {
[215]924 print "unknown command: $command\n\n";
[205]925 usage();
926 check_env();
927 }
928
[209]929 # cleanup (svn-commit.tmp)
[205]930 # commitall
931 # revert
[215]932 # activate
[227]933 # rm
[186]934}
Note: See TracBrowser for help on using the repository browser.