source: trunk/dasscm/dasscm@ 243

Last change on this file since 243 was 239, checked in by joergs, on Oct 9, 2008 at 12:07:00 AM

perltidy

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