3 # Support for importing a source collection into CVS.
4 # Tries to prevent the user from the most common pitfalls (like creating
5 # new top-level repositories or second-level areas accidentally), and
6 # cares to do some of the `dirty' work like maintaining the modules
7 # database accordingly.
9 # Written by Jörg Wunsch, 95/03/07, and placed in the public domain.
13 require "complete.pl";
21 $status = &Getopts("nv");
23 $dont_do_it = "-n" if $opt_n;
25 print STDERR '$FreeBSD$' . "\n"; # 'emacs kludge
28 die "usage: $0 [-v] [-n] [moduledir]\n" .
29 " -n: don't do any commit, show only\n" .
30 " -v: show program version\n"
31 unless $status && $#ARGV <= 0;
34 $moduledir = $ARGV[0];
41 # find all subdirectories under @_
42 # ignore all CVS entries, dot entries, and non-directories
45 local(@ls, @rv, $fname);
47 opendir(DIR, $base) || die "Cannot find dir $base.\n";
54 foreach $fname (@ls) {
55 next if $fname =~ /^CVS/ || $fname eq "Attic"
56 || $fname =~ /^\./ || ! -d "$base/$fname";
66 # look if the first parameter is contained in the list following it
67 local($item, @list) = @_;
72 return 1 if $i eq $item;
81 # first, get some terminal attributes
84 $so = `tput md`; $se = `tput me`;
86 # if no bold mode available, use standout mode
88 $so = `tput so`; $se = `tput se`;
91 # try if we can underscore
92 $us = `tput us`; $ue = `tput ue`;
93 # if we don't have it available, or same as bold/standout, disable it
94 if ($us eq "" || $us eq $so) {
98 # look how many columns we've got
99 if($ENV{'COLUMNS'} ne "") {
100 $columns = $ENV{'COLUMNS'};
101 } elsif(-t STDIN) { # if we operate on a terminal...
104 open(STTY, "stty -a|");
105 $_ = <STTY>; # try getting the tty win structure value
109 foreach $word (split) {
110 $columns = $tmp if $word eq "columns;"; # the number preceding
117 $columns = 80 unless $columns >= 5;
123 # pretty-print a list
124 # imports: global variable $columns
126 local($longest,$i,$item,$cols,$width);
128 # find the longest item
130 foreach $item (@items) {
132 $longest = $i if $longest < $i;
134 $width = $longest + 1;
135 $cols = int($columns / $width);
138 foreach $item (@items) {
143 print ' ' x ($width - length($item));
146 print "\n" unless $i == 0;
151 # get the CVS repository(s)
153 die "You need to have the \$CVSROOT variable set.\n"
154 unless $ENV{'CVSROOT'} ne "";
156 # get the list of available repositories
157 $cvsroot = $ENV{'CVSROOT'};
158 $cvsroot = (split(/:/, $cvsroot, 2))[1] if $cvsroot =~ /:/;
159 @reps = &lsdir($cvsroot);
165 # list all known CVS modules
166 local(%rv, $mname, $mpath, $_);
170 open(CVS, "cvs co -c|");
173 ($mname,$mpath) = split;
174 next if $mname eq "";
175 $rv{$mname} = $mpath;
185 # check a given string for tag rules
186 local($s, $name) = @_;
189 if($name eq "vendor") { $regexp = '^[A-Z][A-Z0-9_]*$'; }
190 elsif($name eq "release") { $regexp = '^[a-z][a-z0-9_]*$'; }
192 print STDERR "Internal error: unknown tag name $name\n";
196 if($s !~ /$regexp/) {
197 print "\a${us}Valid $name tags must match the regexp " .
201 if($s =~ /^RELENG/) {
202 print "\a${us}Tags must not start with the word \"RELENG\".${ue}\n";
216 print "${so}Import from which directory?${se}\n";
217 @dirs = (@dirs, ".");
219 $moduledir = &Complete("Which? [.]: ", @dirs);
220 $moduledir = "." unless $moduledir ne "";
223 chdir $moduledir || die "Cannot chdir to $moduledir\n";
225 print "${so}Available repositories:${se}\n";
228 # the following kludge prevents the Complete package from starting
229 # over with the string just selected; Complete should better provide
230 # some reinitialize method
231 $Complete'return = ""; $Complete'r = 0;
234 &Complete("Enter repository (<TAB>=complete, ^D=show): ",
237 die "\aYou cannot create new repositories with this script.\n"
238 unless &contains($selected, @reps);
242 print "\n${so}Selected repository:${se} ${us}$rep${ue}\n";
245 @areas = &lsdir("$cvsroot/$rep");
247 print "${so}Existent areas in this repository:${se}\n";
250 $Complete'return = ""; $Complete'r = 0;
253 &Complete("Enter area name (<TAB>=complete, ^D=show): ",
256 print "\a${us}Warning: this will create a new area.${ue}\n"
257 unless &contains($selected, @areas);
259 $area = "$rep/$selected";
261 print "\n${so}[Working on:${se} ${us}$area${ue}${so}]${se}\n";
263 %cvsmods = &lsmodules();
267 print "${so}Gimme the module name:${se} ";
271 if ($modname eq "") {
272 print "\a${us}You cannot use an empty module name.${ue}\n";
275 last if !$cvsmods{$modname};
276 print "\a${us}This module name does already exist; do you intend to\n" .
277 "perform a vendor-branch import to the existing sources?${ue}: ";
279 if ($rep =~ /\s*[yY]/) {
280 ($area,$modpath) = split(/\//,$cvsmods{$modname},2);
284 print "${us}Choose another name.${ue}\n";
291 print "${so}Enter the module path:${se} $area/";
295 if ($modpath eq "") {
296 print "\a${us}You cannot use an empty module path.${ue}\n";
299 last if ! -d "$cvsroot/$area/$modpath";
300 print "\a${us}This module path does already exist; " .
301 "choose another one.${ue}\n";
306 $dir1 = "$cvsroot/$area";
309 @newdirs = (@newdirs, "$dir2") if ! -d $dir1;
311 foreach $ele (split(/\//, $modpath)) {
312 $dir1 = "$dir1/$ele";
313 $dir2 = "$dir2/$ele";
314 @newdirs = (@newdirs, "$dir2") if ! -d $dir1;
317 print "${so}You're going to create the following new directories:${se}\n";
324 print "${so}Enter a \`vendor\' tag (e. g. the authors ID):${se} ";
328 last if &checktag($vtag, "vendor");
333 print "${so}Enter a \`release\' tag (e. g. the version #):${se} ";
337 last if &checktag($rtag, "release");
342 print "${so}This is your last chance to interrupt, " .
343 "hit <return> to go on:${se} ";
347 if (!$branchimport) {
349 foreach $tmp (sort(keys(%cvsmods))) {
350 if($tmp gt $modname) {
356 # we are going to append our module
360 $cmd = "/^${mod}[ \t]/\ni\n";
363 print "${so}Checking out the modules database...${se}\n";
364 system("cvs co modules") && die "${us}failed.\n${ue}";
366 print "${so}Inserting new module...${se}\n";
367 open(ED, "|ed modules/modules") || die "${us}Cannot start ed${ue}\n";
368 print(ED "${cmd}${modname} " . ' ' x (15 - length($modname)) .
369 "$area/${modpath}\n.\nw\nq\n");
372 print "${so}Commiting new modules database...${se}\n";
373 system("cvs $dont_do_it commit -m \" " .
374 "${modname} --> $area/${modpath}\" modules")
375 && die "Commit failed\n";
377 # we always release "modules" to prevent duplicate
378 system("cvs -Q release -d modules");
381 print "${so}Importing source. Enter a commit message in the editor.${se}\n";
383 system("cvs $dont_do_it import $area/$modpath $vtag $rtag");
385 print "${so}You are done now. Go to a different directory, perform a${se}\n".
386 "${us}cvs co ${modname}${ue} ${so}command, and see if your new module" .
387 " builds ok.${se}\n";
389 print "\nPlease don't forget to edit the parent Makefile to add what you\n".
396 ${so}Since you did not allow to commit anything, you'll have${se}
397 ${so}to remove the edited modules' database yourself.${se}
398 ${so}To do this, perform a${se}
399 ${us}cd ${moduledir}; cvs -Q release -d modules${ue}