/stdhome

To get this branch, use:
bzr branch http://bzr.ed.am/stdhome

« back to all changes in this revision

Viewing changes to lib/stdhome/walker/walker.py

  • Committer: Tim Marston
  • Date: 2014-03-19 20:02:10 UTC
  • Revision ID: tim@ed.am-20140319200210-b6nm63rpktfmw0l3
changed working of output

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
 
22
22
import os
23
 
import stdhome.the as the
24
23
 
25
24
 
26
25
class Walker:
38
37
                walk_list that fall under the directory are skipped.
39
38
                """
40
39
 
41
 
                if the.verbose >= 3: print "walking [%s]" % self.__class__.__name__
42
 
 
43
40
                skip = ''
 
41
 
44
42
                for rel_file in self.walk_list:
45
43
 
46
44
                        # if we're skipping, skip entries in subdirectories, or turn off
51
49
                                else:
52
50
                                        skip = ''
53
51
 
54
 
                        src = Walker.File( os.path.join( self.src_dir, rel_file ) )
55
 
                        dst = Walker.File( os.path.join( self.dst_dir, rel_file ) )
56
 
 
57
 
                        # process ths entry
58
 
                        recurse = self.process( rel_file, src, dst )
 
52
                        src_file = os.path.join( self.src_dir, rel_file )
 
53
                        dst_file = os.path.join( self.dst_dir, rel_file )
 
54
 
 
55
                        src_type = Walker.get_file_type( src_file )
 
56
                        dst_type = Walker.get_file_type( dst_file )
 
57
 
 
58
                        recurse = self.process(
 
59
                                rel_file, src_file, src_type, dst_file, dst_type )
59
60
 
60
61
                        # Set up skipping, as required.  Note that we don't check to see if
61
62
                        # we're dealing with a directory here.  We can't, because we've no
62
63
                        # way of knowing what to check.  It could be src_type or dst_type
63
64
                        # (if src_dir or dst_dir was used to generate the walk list) or it
64
65
                        # could be neither (if the walk list came from somewhere else).  But
65
 
                        # it shouldn't matter: we add a path seperateor (os.sep) to the end
66
 
                        # of the filename, so it wuill only match files that are descendents
67
 
                        # of a directory with the name of this file.
68
 
                        if not recurse: skip = rel_file + os.sep
69
 
 
70
 
 
71
 
        class File:
72
 
 
73
 
                def __init__( self, full_file ):
74
 
                        self.file = full_file
75
 
                        if not os.path.exists( self.file ):
76
 
                                self.type = '_'
77
 
                        elif os.path.isfile( self.file ):
78
 
                                self.type = 'f'
79
 
                        elif os.path.isdir( self.file ):
80
 
                                self.type = 'd'
81
 
                        else:
82
 
                                self.type = '?'
83
 
                        if os.path.islink( self.file ):
84
 
                                self.link_type = self.type
85
 
                                self.type = 'l'
86
 
                        else:
87
 
                                self.link_type = False
88
 
 
89
 
                def get_type_name( self ):
90
 
                        if self.type == 'l': return 'symlink'
91
 
                        elif self.type == 'f': return 'file'
92
 
                        elif self.type == 'd': return 'directory'
93
 
                        elif self.type == '_': return 'missing'
94
 
                        else: return 'unknown'
95
 
 
96
 
                def __str__( self ):
97
 
                        type = self.type
98
 
                        if( self.link_type ): type += '/' + self.link_type
99
 
                        return 'File( %s (%s) )' % ( self.file, type )
100
 
 
101
 
 
102
 
        @staticmethod
103
 
        def generate_walk_list( rel_file = '', full_dir = None ):
 
66
                        # it shouldn't matter.  We adding an os.pathset to the end of the
 
67
                        # filename, so it wuill only match files that are descendents of a
 
68
                        # directory with the name of this file.
 
69
                        if not recurse: skip = rel_file + os.pathsep
 
70
 
 
71
 
 
72
        @staticmethod
 
73
        def get_file_type( full_file ):
 
74
                """Returns the type of a given file, at the time of calling.  Types are 'd' for
 
75
                directory, 'f' for file, 'l' for symlink, '_' for missing and '?' for
 
76
                anything else.
 
77
                """
 
78
 
 
79
                if not os.path.lexists( full_file ):
 
80
                        return '_'
 
81
                elif os.path.islink( full_file ):
 
82
                        return 'l'
 
83
                elif os.path.isfile( full_file ):
 
84
                        return 'f'
 
85
                elif os.path.isdir( full_file ):
 
86
                        return 'd'
 
87
                else:
 
88
                        return '?'
 
89
 
 
90
 
 
91
        @staticmethod
 
92
        def generate_walk_list( full_dir, rel_file = '' ):
104
93
                """Returns a list of files and directories in full_dir, specified as relative
105
94
                files (relative to full_dir), breadth first.
106
95
                """
107
96
 
108
 
                # default place to walk
109
 
                if full_dir is None: full_dir = the.repo.full_dir
110
 
 
111
97
                # ignore some files
112
 
                if rel_file in [ '.bzr', '.bzrignore', '.stdhome', '.stdhomerc' ]:
113
 
                        return list()
 
98
                if rel_file in { '.bzr', '.stdhome' }: return list()
114
99
 
115
100
                full_file = os.path.join( full_dir, rel_file )
116
101
 
123
108
                        ret = [ rel_file ] if rel_file != '' else []
124
109
                        for file in os.listdir( full_file ):
125
110
                                ret.extend( Walker.generate_walk_list(
126
 
                                        os.path.join( rel_file, file ), full_dir ) )
 
111
                                        full_dir, os.path.join( rel_file, file ) ) )
127
112
                        return sorted( ret )
128
113
 
129
114
                # other kinds are invalid
130
115
                else:
131
116
                        raise RuntimeError(
132
117
                                'unknown/exotic file: %s' % full_file )
 
118
 
 
119
 
 
120
        @staticmethod
 
121
        def name_of_type( type ):
 
122
                if type == 'd': return 'a directory'
 
123
                elif type == 'f': return 'a file'
 
124
                elif type == 'l': return 'a symlink'
 
125
                elif type == '_': return 'missing'
 
126
                else: return 'something exotic'