[The problem that this patch is getting at is mentioned at http://www.cyclic.com/cvs/dev-wrap.html; that is, that combining "run it through a filter" and "treat a directory as one entity" are not necessarily two features which should go together. -kingdon] Date: Wed, 19 Feb 1997 19:20:49 -0700 From: Gordon Matzigkeit To: bug-cvs@prep.ai.mit.edu >Submitter-Id: net >Originator: Gordon Matzigkeit >Organization: net >Confidential: no >Synopsis: there is no good way to conveniently wrap only files >Severity: non-critical >Priority: medium >Category: cvs >Class: change-request >Release: cvs-1.9 >Environment: System: Linux bambam 2.0.16 #2 Mon Sep 2 12:47:56 MDT 1996 i586 Architecture: i586 >Description: I use a .cvswrappers file to run dos2unix before I check files into the repository. I don't want this wrapper to match names that are directories. Ideally, the .cvswrappers file would allow an option like: # -T file type value: FILE or DIRECTORY So, then I could put: # Prevent any MS-DOS-corrupted files from infecting the Unix CVS repository. * -t 'dos2unix %s %s' -T 'FILE' without fear of running dos2unix on a directory. >How-To-Repeat: Put the following line in .cvswrappers: * -t 'dos2unix %s %s' The results are not pleasant... all created directories are identified as ``wrappers'', so it becomes impossible to commit new directories. The alternative is to maintain a different cvswrappers entry for every known file specification, which is a maintainance headache, and causes namespace pollution (can't commit any directory with the same name as a file). >Fix: The following patches add support for the above mentioned -T flag. I am not happy with the way that wrapper.c is organized... especially the parser seems kludgy, but at least my changes do not introduce bugs that are any worse. diff -u cvs.h.orig cvs.h --- cvs.h.orig Wed Oct 2 00:03:59 1996 +++ cvs.h Wed Feb 19 18:07:58 1997 @@ -699,6 +699,7 @@ /* Wrappers. */ typedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod; +typedef enum { WRAP_BOTH, WRAP_DIR, WRAP_FILE } WrapFileType; typedef enum { /* -t and -f wrapper options. Treating directories as single files. */ WRAP_TOCVS, diff -u mkmodules.c.orig mkmodules.c --- mkmodules.c.orig Mon Aug 26 12:18:07 1996 +++ mkmodules.c Wed Feb 19 19:14:27 1997 @@ -180,13 +180,21 @@ "# wildcard [option value][option value]...\n", "#\n", "# where option is one of\n", + "# -T entry type value: FILE or DIR\n", "# -f from cvs filter value: path to filter\n", "# -t to cvs filter value: path to filter\n", "# -m update methodology value: MERGE or COPY\n", + "# -k default -k rcs option to use on import or add\n", "#\n", "# and value is a single-quote delimited value.\n", "#\n", "# For example:\n", + "#\n", + "# Tar and zip any .nib directories or files, and copy into repository.\n", + "#*.nib -f 'gunzipuntar' -t 'targzip' -m 'COPY'\n", + "#\n", + "# Prevent DOS-corrupted files from infecting the CVS repository.\n", + "#* -t 'dos2unix %s %s' -T 'FILE'\n", NULL }; diff -u wrapper.c.orig wrapper.c --- wrapper.c.orig Fri Aug 23 09:30:21 1996 +++ wrapper.c Wed Feb 19 19:14:25 1997 @@ -19,6 +19,7 @@ wildcard [option value][option value]... where option is one of + -T entry type value: FILE or DIR -f from cvs filter value: path to filter -t to cvs filter value: path to filter -m update methodology value: MERGE or COPY @@ -28,6 +29,8 @@ E.g: *.nib -f 'gunzipuntar' -t 'targzip' -m 'COPY' + # Prevent DOS-corrupted files from infecting the CVS repository. + * -t 'dos2unix %s %s' -T 'FILE' */ @@ -36,6 +39,7 @@ char *tocvsFilter; char *fromcvsFilter; char *rcsOption; + WrapFileType fileType; WrapMergeMethod mergeMethod; } WrapperEntry; @@ -121,6 +125,11 @@ and (more importantly) where we found it. */ error (0, 0, "\ -m wrapper option is not supported remotely; ignored"); + if (wrap_list[i]->fileType != WRAP_BOTH) + /* For greater studliness we would print the offending option + and (more importantly) where we found it. */ + error (0, 0, "\ +-T wrapper option is not supported remotely; ignored"); if (wrap_list[i]->rcsOption != NULL) { send_to_server ("Argument -W\012Argument ", 0); @@ -307,6 +316,14 @@ free (e.rcsOption); e.rcsOption = xstrdup (temp); break; + case 'T': + if (*temp=='F' || *temp=='f') + e.fileType = WRAP_FILE; + else if (*temp=='D' || *temp=='d') + e.fileType = WRAP_DIR; + else + e.fileType = WRAP_BOTH; + break; default: break; } @@ -343,8 +360,36 @@ wrap_list[x]->tocvsFilter=e->tocvsFilter; wrap_list[x]->mergeMethod=e->mergeMethod; wrap_list[x]->rcsOption = e->rcsOption; + wrap_list[x]->fileType = e->fileType; } +/* Return 1 if the given filename matches the entry. */ +static int +wrapmatch (e, name) + WrapperEntry *e; + const char *name; +{ + if (fnmatch (e->wildCard, name, 0) == 0) + { + if (e->fileType != WRAP_BOTH) + { + if (isdir (name)) + { + if (e->fileType != WRAP_DIR) + /* We found a directory, but the wildcard was for a file. */ + return 0; + } + else if (e->fileType == WRAP_DIR) + /* We found a file, but the wildcard was for a directory. */ + return 0; + } + return 1; + } + + return 0; +} + + /* Return 1 if the given filename is a wrapper filename */ int wrap_name_has (name,has) @@ -355,7 +400,7 @@ char *temp; for(x=0;xwildCard, name, 0) == 0){ + if (wrapmatch (wrap_list[x], name)){ switch(has){ case WRAP_TOCVS: temp=wrap_list[x]->tocvsFilter; @@ -384,8 +429,9 @@ int x,count=wrap_count+wrap_saved_count; for(x=0;xwildCard, name, 0) == 0) + if (wrapmatch (wrap_list[x], name)) return wrap_list[x]; + return (WrapperEntry *)NULL; }