Changeset 1726

Show
Ignore:
Timestamp:
11/03/08 23:09:03 (2 months ago)
Author:
Chuck.Esterbrook
Message:

Enhance le to take paths on the command line so its actions can be limited to particular files and directories.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • cobra/trunk/Supplements/le.cobra

    r1725 r1726  
    1212 
    1313Run with -h for usage help. 
     14 
     15Notes 
     16 
     17 * The program looks at the extension of a file to determine if it is text or binary. While this is 
     18   less technically accurate than examining file contents and also requires the extension lists to 
     19   be occasionally augmented, it is very efficient--many files do not have to be opened. 
     20 
    1421""" 
    1522 
     
    2532class LineEndings 
    2633 
     34        var _excludeNamesSpec   = '.svn _svn' 
     35        var _binExtensionsSpec  = 'dll doc exe pdb mdb gif png pyc pyo jpg jpeg snk tif tiff xls' 
     36        var _textExtensionsSpec = 'bat c cobra config cpp cs css dif diff h htm html kv m patch py sh sql svg text txt xhtml xml' 
     37 
     38        var _excludeNamesCache   = List<of String>() 
     39        var _binExtensionsCache  = List<of String>() 
     40        var _textExtensionsCache = List<of String>() 
     41 
    2742        var _action as Action 
    2843 
     
    3045        var _notCrLfRegEx = Regex(r'[^\r]\n') 
    3146 
    32         var _exts = Dictionary<of String, bool>()  # should be Set 
    33  
    34         get excludeNames as List<of String> 
    35                 return List<of String>('.svn _svn'.split) 
    36  
    37         get binExtensions as List<of String> 
    38                 return List<of String>('dll doc exe pdb mdb gif png pyc pyo jpg jpeg snk tif tiff xls'.split) 
    39  
    40         get textExtensions as List<of String> 
    41                 return List<of String>('bat c cobra config cpp cs css dif diff h htm html kv m patch py sh sql svg text txt xhtml xml'.split) 
     47        var _exts = Set<of String>() 
     48 
     49        get excludeNames as IList<of String> 
     50                if not _excludeNamesCache.count 
     51                        _excludeNamesCache = List<of String>(_excludeNamesSpec.split) 
     52                return _excludeNamesCache 
     53 
     54        get binExtensions as IList<of String> 
     55                if not _binExtensionsCache.count 
     56                        _binExtensionsCache = List<of String>(_binExtensionsSpec.split) 
     57                return _binExtensionsCache 
     58 
     59        get textExtensions as IList<of String> 
     60                if not _textExtensionsCache.count 
     61                        _textExtensionsCache = List<of String>(_textExtensionsSpec.split) 
     62                return _textExtensionsCache 
    4263 
    4364        def main is shared 
    44                 LineEndings().run 
     65                LineEndings().run(CobraCore.commandLineArgs) 
    4566 
    4667        def printHelp 
    47                 print 'This program always starts with the current directory and descends into subdirectories.' 
    48                 print 'The program source contains names to ignore (.svn/_svn) and extension types (text vs. binary).' 
    49                 print 
    50                 print 'With -r or -report, information is printed and no actions are taken.' 
    51                 print 'With -to-unix, files that are detected with DOS endings are rewritten.' 
    52                 print 'With -to-dos, files that are detected with UNIX endings are rewritten.' 
    53  
    54         def run 
     68                print 'le <option> \[<paths>]' 
     69                print 
     70                print '  -r or -report: information is printed and no actions are taken.' 
     71                print '  -to-unix: files that are detected with DOS endings are rewritten.' 
     72                print '  -to-dos: files that are detected with UNIX endings are rewritten.' 
     73                print 
     74                print 'You can specify one or more files or directories after the option.' 
     75                print 'Or if you specify none, then the currect directory is processed.' 
     76                print 'Directories are always processed recursively.' 
     77                print 
     78                print 'The program source contains names to ignore (.svn/_svn) and ' 
     79                print 'extension types (text vs. binary).' 
     80                print 
     81 
     82        def reset 
     83                _action = Action.None 
     84                _exts.clear 
     85                _excludeNamesCache.clear 
     86                _binExtensionsCache.clear 
     87                _textExtensionsCache.clear 
     88 
     89        def run(args as List<of String>) 
     90                require args.count > 0  # first arg is program name/path 
    5591                print 'Line Endings' 
    5692                print 
    57                 _action = Action.None 
    58                 args = CobraCore.commandLineArgs 
     93                .reset 
    5994                if args.count == 1 
    6095                        .printHelp 
    6196                        return 
    62                 else if args.count == 2 
    63                         arg = args[1] 
    64                         branch arg 
    65                                 on '-h' or '-help' or '--help' 
    66                                         .printHelp 
    67                                         return 
    68                                 on '-r' or '-report' 
    69                                         _action = Action.None 
    70                                 on '-to-unix' 
    71                                         _action = Action.ToUnix 
    72                                 on '-to-dos' 
    73                                         _action = Action.ToDos 
    74                                 else 
    75                                         print 'Unknown option. Try -h' 
    76                                         return 
    77                 else 
    78                         print 'Too many arguments. Try -h' 
     97                arg = args[1] 
     98                branch arg 
     99                        on '-h' or '-help' or '--help' 
     100                                .printHelp 
     101                                return 
     102                        on '-r' or '-report' 
     103                                _action = Action.None 
     104                        on '-to-unix' 
     105                                _action = Action.ToUnix 
     106                        on '-to-dos' 
     107                                _action = Action.ToDos 
     108                        else 
     109                                print 'Unknown option. Try -h' 
     110                                return 
     111                assert args.count >= 2 
     112                if args.count == 2 
     113                        args.add('.')  # current directory 
     114 
     115                # CC: 
     116                # paths, badPaths = for arg in args[2:] splitby Directory.exists(arg) or File.exists(arg) 
     117                # kind of like: 
     118                # paths = for arg in args[2:] where Directory.exists(arg) or File.exists(arg) 
     119 
     120                paths = List<of String>() 
     121                for arg in args[2:] 
     122                        if File.exists(arg) 
     123                                paths.add(arg) 
     124                        else if Directory.exists(arg) 
     125                                paths.add(arg) 
     126                        else 
     127                                print 'Unknown path:', arg 
     128                                return 
     129 
    79130                if true 
    80131                        print 'Action: ' stop 
     
    83134                                on Action.ToUnix, print 'Convert line endings to Unix' 
    84135                                on Action.ToDos,  print 'Convert line endings to DOS/Windows' 
    85                 print 
    86                 .scanDir('.') 
    87                 if true 
    88                         exts = List<of String>(_exts.keys) 
    89                         exts.sort 
    90                         print 'Extensions found: ' stop 
    91                         for ext in exts 
    92                                 print '[ext] ' stop 
    93136                        print 
    94137 
     138                .scanPaths(paths) 
     139                .summarizeExtensions 
     140 
     141        def scanPaths(paths as IList<of String>) 
     142                for path in paths 
     143                        # print 'scanning:', path 
     144                        if Directory.exists(path) 
     145                                .scanDir(path) 
     146                        else if File.exists(path) 
     147                                .scanFile(path) 
     148                        else 
     149                                print 'warning: cannot find:', path 
     150         
    95151        def scanDir(path as String) 
    96152                assert not path.endsWith('.svn') 
    97                 excludeNames = .excludeNames 
    98                 binExts = .binExtensions 
    99                 textExts = .textExtensions 
    100153                dirInfo = DirectoryInfo(path) 
    101154                for fi in dirInfo.getFiles 
    102                         if fi.name in excludeNames, continue 
    103                         ext = (fi.extension ? '').toLower 
    104                         if ext.startsWith('.'), ext = ext[1:] 
    105                         _exts[ext] = true 
    106                         if ext in binExts 
    107                                 print 'skipping bin file      : [fi]' 
    108                         else if ext in textExts or ext == '' 
    109                                 # In practice, I find that files without extensions are text files. 
    110                                 # Usually captured text output from a command or a shell script. 
    111                                 type = .lineEndingsType(fi) 
    112                                 pad = if(type=='dos', ' ', '') 
    113                                 print 'found text file ([type]) [pad]: [fi]' 
    114                                 .act(type, fi) 
    115                         else 
    116                                 print 'unknown file type      : "[ext]" for [fi]' 
     155                        .scanFile(fi) 
    117156                for di in dirInfo.getDirectories 
    118                         if di.name in excludeNames, continue 
     157                        if di.name in .excludeNames, continue 
    119158                        .scanDir(di.fullName) 
     159                         
     160        def scanFile(path as String) 
     161                .scanFile(FileInfo(path)) 
     162 
     163        def scanFile(fi as FileInfo) 
     164                if fi.name in .excludeNames, return 
     165                ext = (fi.extension ? '').toLower 
     166                if ext.startsWith('.'), ext = ext[1:] 
     167                _exts.add(ext) 
     168                if ext in .binExtensions 
     169                        print 'skipping bin file      : [fi]' 
     170                else if ext in .textExtensions or ext == '' 
     171                        # In practice, I find that files without extensions are text files. 
     172                        # Usually captured text output from a command or a shell script. 
     173                        type = .lineEndingsType(fi) 
     174                        pad = if(type=='dos', ' ', '') 
     175                        print 'found text file ([type]) [pad]: [fi]' 
     176                        .act(type, fi) 
     177                else 
     178                        print 'unknown file type      : "[ext]" for [fi]' 
    120179 
    121180        def lineEndingsType(fi as FileInfo) as String 
     
    167226                                File.move(newName, fi.fullName) 
    168227                                print '                         Converted' 
     228 
     229        def summarizeExtensions 
     230                exts = List<of String>(_exts) 
     231                exts.sort 
     232                print 'Extensions found: ' stop 
     233                for ext in exts 
     234                        print '[ext] ' stop 
     235                print