r90: Dodan --change u cp-update
authorDamir Dzeko <Damir.Dzeko@CARNet.hr>
Mon, 26 Dec 2005 20:43:16 +0000 (20:43 +0000)
committerDamir Dzeko <Damir.Dzeko@CARNet.hr>
Mon, 26 Dec 2005 20:43:16 +0000 (20:43 +0000)
cp-update
test/Makefile
test/test1.ok
test/test2.ok
test/test3.ok
test/test4.ok
test/test5.ok
test/test6.ok
test/test7.ok [new file with mode: 0644]
test/test8.ok [new file with mode: 0644]

index d5b2ab2..f4d66be 100755 (executable)
--- a/cp-update
+++ b/cp-update
@@ -3,6 +3,7 @@
 ## Copyright (C) 1998 Hrvoje Niksic
 ## Modification by Zeljko Boros (block entries, removing old entries)
 ## More options and use strict by Zoran Dzelajlija on 2004-02-24
+## Quite a few improvements by Damir Dzeko on 2005-03-18 (see bellow)
 ##
 ## This program is free software; you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
@@ -22,7 +23,7 @@
 ## -> reformated code, introduced coding conventions
 ## -> increased reliability through atomic actualization
 ## -> everything is done in the memory - more mem, less i/o
-## -> removed append mode - in-place editing considered harmfull
+## -> removed append mode - in-place editing considered harmful
 ## -> added in-place mode as option
 
 use strict;
@@ -54,12 +55,16 @@ $UsageLong = "
            -r | --remove            Remove entry PACKAGE from FILE.
                                     Default is to add lines from stdin.
 
+           -x | --change            Modify existing block, or add it if
+                                    it does not exist but the begin mark
+                                    can be found.
+
            -m | --allow-multiple    Allow multiple blocks of the same type.
                                     By default, old blocks are replaced with
                                     the new one.
 
            -h | --help              Print this message (usage reference).
-           
+
                 --version           Print version message.
 
   - Placement control:
@@ -115,6 +120,7 @@ use constant INSERT_ON_TOP => 3;
 # InsertRemove modes
 use constant DO_REMOVE => 0;
 use constant DO_INSERT => 1;
+use constant DO_CHANGE => 2;
 
 # Operation defaults
 $InsertRemove = DO_INSERT;
@@ -139,6 +145,9 @@ while (@ARGV) {
   elsif (/^-r$/ || /^--remove$/) {
     $InsertRemove = DO_REMOVE;
   }
+  elsif (/^-x$/ || /^--change$/) {
+    $InsertRemove = DO_CHANGE;
+  }
   elsif (/^-m$/ || /^--allow-multi(?:ple)?$/) {
     $Multi = 1;
   }
@@ -190,6 +199,10 @@ while (@ARGV) {
     unshift(@ARGV, $_);
     last;
   }
+  
+  if ($Multi and DO_CHANGE == $InsertRemove) {
+    die "$ProgramName: Cannot use both `--change' and `--allow-multiple'\n";
+  }
 }
 
 $Package = shift  or  die $UsageShort;
@@ -239,7 +252,11 @@ do_it() and exit(0);
 
 sub do_it {
   slurp();
-  if (DO_INSERT == $InsertRemove) {
+  if (DO_CHANGE == $InsertRemove) {
+    $StdinContent = &stdin_content;
+    change() or add();
+  }
+  elsif (DO_INSERT == $InsertRemove) {
     $StdinContent = &stdin_content;
     del() unless $Multi;
     add();
@@ -338,6 +355,51 @@ sub del() {
   return scalar(@Lines); # whatever
 }
 
+sub change() {
+  my ($mytrailer, $mybegin, $myend) =
+    ($Trailer, $MarkBegin, $MarkEnd);
+
+  my ($bm_found, $em_found); # begin/end mark found indicator
+
+  # Make the strings regexp-friendly by quoting non-word chars.
+  $mybegin   =~ s/\W/\\$&/g;
+  $myend     =~ s/\W/\\$&/g;
+  $mytrailer =~ s/\W/\\$&/g;
+
+  my (@filtered, $done, $skip);
+  $done = 0; # job done once
+  $skip = 0; # skip original block
+  foreach (@Lines) {
+    if (! $done and $skip > 0) {
+      if (/^$myend(?:$mytrailer)?$/o) {
+        ++ $done; # skipped all that was to skip
+      } else {
+        ++ $skip; # count lines being skipped
+      }
+    }
+    elsif (0 == $skip and $_ =~ /^$mybegin(?:$mytrailer)?$/o) {
+      push (@filtered, $StdinContent);
+      $skip = 1;
+    }
+    else {
+      push (@filtered, $_)
+    }
+    # for safety check:
+    $bm_found = 1 if (/^$mybegin(?:$mytrailer)?$/o);
+    $em_found = 1 if (/^$myend(?:$mytrailer)?$/o);
+  }
+  if ($bm_found and $em_found) {
+    -- $skip; # correct the counter
+    DEBUG and print STDERR "Replaced block of $skip lines\n";
+    @Lines = @filtered;
+  }
+  elsif ($bm_found and ! $em_found) {
+    # safety exit    
+    die "$ProgramName: no end-mark after begin-mark!\n";
+  }
+  return $done;
+}
+
 # written by ddzeko@srce.hr, 2005-03-18
 # to improve reliabilitah :)
 #
index 5c19de1..e0117a8 100644 (file)
@@ -6,12 +6,12 @@
 # path to cp-update script
 CPUPDATE=../cp-update
 
-tests: test0 test1 test2 test3 test4 test5 test6
+tests: test0 test1 test2 test3 test4 test5 test6 test7 test8
        @echo "All tests completed successfully"
        @cp test-file.start test-file
        
 clean: test0 test-file.start
-       rm -f test[0-9] test[0-9][0-9] test-file.[0-9]*
+       rm -f test[0-9] test[0-9][a-zA-Z0-9] test-file.[0-9]*
 
 # prepare everything for test sequence
 test0: test-file.start
@@ -68,9 +68,30 @@ test5:
        mv test-new $@
        echo Succeeded $@
 
+# change/replace existing blocks
+# - even if they do not previously exist (fall-back to insert)
+test6:
+       perl -e 'print "test line $$_ by $$ARGV[0]\n" for 14..18;' testChange \
+                | $(CPUPDATE) -x -i 'something' testChange test-file
+       cp test-file test-new
+       cmp test-new $@.ok
+       mv test-new $@
+       echo Succeeded $@
+
+# change/replace existing blocks
+# - just change it Sam
+test7: test6
+       cp test6 test6c
+       perl -e 'print "test line $$_ by $$ARGV[0]\n" for 22..26;' testChange \
+                | $(CPUPDATE) -x -i 'something' testChange test6c
+       cp test6c test-new
+       cmp test-new $@.ok
+       mv test-new $@
+       echo Succeeded $@
+
 # now remove everything
-test6: test1 test2 test3 test4 test5
-       for i in test[1-4]; do $(CPUPDATE) -r $$i test-file; done
+test8: test1 test2 test3 test4 test5 test6
+       for i in test[1-4] testChange; do $(CPUPDATE) -r $$i test-file; done
        $(CPUPDATE) -r -c ';' test5 test-file
        cp test-file.start $@.ok
        echo >> $@.ok
index 9d5ab7a..cc46434 100644 (file)
@@ -1,4 +1,7 @@
 This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
 so they can check is everything ok with the script. Empty line:
 
 # Here we have a piece that looks like a comment
@@ -27,6 +30,3 @@ string after the package name
 # Begin update by CARNet package broken2
 
 It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
index ebc464d..c8ecc03 100644 (file)
@@ -2,6 +2,9 @@
 Block inserted by test2
 # End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
 This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
 so they can check is everything ok with the script. Empty line:
 
 # Here we have a piece that looks like a comment
@@ -30,6 +33,3 @@ string after the package name
 # Begin update by CARNet package broken2
 
 It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
index 5bd66d8..e4ab5ce 100644 (file)
@@ -2,6 +2,9 @@
 Block inserted by test2
 # End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
 This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
 so they can check is everything ok with the script. Empty line:
 
 # Here we have a piece that looks like a comment
@@ -33,6 +36,3 @@ string after the package name
 # Begin update by CARNet package broken2
 
 It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
index 91077ac..cd33d8a 100644 (file)
@@ -2,6 +2,9 @@
 Block inserted by test2
 # End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
 This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
 so they can check is everything ok with the script. Empty line:
 
 # Here we have a piece that looks like a comment
@@ -33,9 +36,6 @@ string after the package name
 # Begin update by CARNet package broken2
 
 It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
 # Begin update by CARNet package test4 -- DO NOT DELETE THIS LINE!
 Block inserted by test4
 # End update by CARNet package test4 -- DO NOT DELETE THIS LINE!
index 32192cd..4f557b6 100644 (file)
@@ -2,6 +2,9 @@
 Block inserted by test2
 # End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
 This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
 so they can check is everything ok with the script. Empty line:
 
 # Here we have a piece that looks like a comment
@@ -40,9 +43,6 @@ string after the package name
 # Begin update by CARNet package broken2
 
 It's the end of the file and guess what? This line does not end with \n
-# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
-Block inserted by test1
-# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
 # Begin update by CARNet package test4 -- DO NOT DELETE THIS LINE!
 Block inserted by test4
 # End update by CARNet package test4 -- DO NOT DELETE THIS LINE!
index 1e6e4b7..80a1d21 100644 (file)
@@ -1,4 +1,10 @@
+# Begin update by CARNet package test2 -- DO NOT DELETE THIS LINE!
+Block inserted by test2
+# End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
 This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
 so they can check is everything ok with the script. Empty line:
 
 # Here we have a piece that looks like a comment
@@ -7,13 +13,30 @@ so they can check is everything ok with the script. Empty line:
 
 [samba]
   brasil = de Janeiro
+; Begin update by CARNet package test5 -- DO NOT DELETE THIS LINE!
+test line 1 by test5
+test line 2 by test5
+test line 3 by test5
+test line 4 by test5
+test line 5 by test5
+; End update by CARNet package test5 -- DO NOT DELETE THIS LINE!
 
 <apache>
   mohican = the last
 </apache>
+# Begin update by CARNet package test3 -- DO NOT DELETE THIS LINE!
+Block inserted by test3
+# End update by CARNet package test3 -- DO NOT DELETE THIS LINE!
 
 options {
   something +more;
+# Begin update by CARNet package testChange -- DO NOT DELETE THIS LINE!
+test line 14 by testChange
+test line 15 by testChange
+test line 16 by testChange
+test line 17 by testChange
+test line 18 by testChange
+# End update by CARNet package testChange -- DO NOT DELETE THIS LINE!
 }
 
 # update this
@@ -27,3 +50,6 @@ string after the package name
 # Begin update by CARNet package broken2
 
 It's the end of the file and guess what? This line does not end with \n
+# Begin update by CARNet package test4 -- DO NOT DELETE THIS LINE!
+Block inserted by test4
+# End update by CARNet package test4 -- DO NOT DELETE THIS LINE!
diff --git a/test/test7.ok b/test/test7.ok
new file mode 100644 (file)
index 0000000..989b974
--- /dev/null
@@ -0,0 +1,55 @@
+# Begin update by CARNet package test2 -- DO NOT DELETE THIS LINE!
+Block inserted by test2
+# End update by CARNet package test2 -- DO NOT DELETE THIS LINE!
+This is the top of the test file for cp-update maintenance team
+# Begin update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+Block inserted by test1
+# End update by CARNet package test1 -- DO NOT DELETE THIS LINE!
+so they can check is everything ok with the script. Empty line:
+
+# Here we have a piece that looks like a comment
+; following line says that you should not delete it:
+ -- DO NOT DELETE THIS LINE!
+
+[samba]
+  brasil = de Janeiro
+; Begin update by CARNet package test5 -- DO NOT DELETE THIS LINE!
+test line 1 by test5
+test line 2 by test5
+test line 3 by test5
+test line 4 by test5
+test line 5 by test5
+; End update by CARNet package test5 -- DO NOT DELETE THIS LINE!
+
+<apache>
+  mohican = the last
+</apache>
+# Begin update by CARNet package test3 -- DO NOT DELETE THIS LINE!
+Block inserted by test3
+# End update by CARNet package test3 -- DO NOT DELETE THIS LINE!
+
+options {
+  something +more;
+# Begin update by CARNet package testChange -- DO NOT DELETE THIS LINE!
+test line 22 by testChange
+test line 23 by testChange
+test line 24 by testChange
+test line 25 by testChange
+test line 26 by testChange
+# End update by CARNet package testChange -- DO NOT DELETE THIS LINE!
+}
+
+# update this
+
+# Begin update by CARNet package broken
+this is for compatibility with older version which did not add
+ -- DO NOT DELETE THIS LINE!
+string after the package name
+# End update by CARNet package broken
+
+# Begin update by CARNet package broken2
+
+It's the end of the file and guess what? This line does not end with \n
+# Begin update by CARNet package test4 -- DO NOT DELETE THIS LINE!
+Block inserted by test4
+# End update by CARNet package test4 -- DO NOT DELETE THIS LINE!
diff --git a/test/test8.ok b/test/test8.ok
new file mode 100644 (file)
index 0000000..1e6e4b7
--- /dev/null
@@ -0,0 +1,29 @@
+This is the top of the test file for cp-update maintenance team
+so they can check is everything ok with the script. Empty line:
+
+# Here we have a piece that looks like a comment
+; following line says that you should not delete it:
+ -- DO NOT DELETE THIS LINE!
+
+[samba]
+  brasil = de Janeiro
+
+<apache>
+  mohican = the last
+</apache>
+
+options {
+  something +more;
+}
+
+# update this
+
+# Begin update by CARNet package broken
+this is for compatibility with older version which did not add
+ -- DO NOT DELETE THIS LINE!
+string after the package name
+# End update by CARNet package broken
+
+# Begin update by CARNet package broken2
+
+It's the end of the file and guess what? This line does not end with \n