/stdhome

To get this branch, use:
bzr branch http://bzr.ed.am/stdhome
8 by Tim Marston
added diff command; moved all command to commands subdir; made stage-revert
1
# status.py
5 by Tim Marston
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
2
#
3
# Copyright (C) 2013 to 2014 Tim Marston <tim@edm.am>
4
#
5
# This file is part of stdhome (hereafter referred to as "this program").
6
# See http://ed.am/dev/stdhome for more information.
7
#
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
# GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21
8 by Tim Marston
added diff command; moved all command to commands subdir; made stage-revert
22
import filecmp, os
88 by Tim Marston
python3ification
23
from .walker import Walker
5 by Tim Marston
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
24
import stdhome.the as the
25
26
27
class StatusWalker( Walker ):
28
	"""The status walker compares all files in the repo with those in the home
29
	directory and notes any that have been modified, are missing, or which have
30
	changed type.  It is run, for example, but the "stdhome status" comand.
31
15 by Tim Marston
changed wording of status command output
32
	Walker source:       repo
33
	Walker destination:  home dir
8 by Tim Marston
added diff command; moved all command to commands subdir; made stage-revert
34
	Walker traversing:   repo (unless a walk list is provided)
5 by Tim Marston
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
35
	"""
36
8 by Tim Marston
added diff command; moved all command to commands subdir; made stage-revert
37
	def __init__( self, walk_list = None ):
15 by Tim Marston
changed wording of status command output
38
		self.src_dir = the.repo.full_dir
39
		self.dst_dir = the.full_home_dir
8 by Tim Marston
added diff command; moved all command to commands subdir; made stage-revert
40
		self.walk_list = walk_list if walk_list is not None else \
82 by Tim Marston
added general reporting to CopyBase and configured it via copy-in and copy-out
41
						 self.generate_walk_list( the.repo.full_dir )
5 by Tim Marston
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
42
43
		self.modified = list()
44
		self.missing = list()
45
		self.changed = list()
46
47
16 by Tim Marston
walker now passes Walker.File objects to process(), which includes file name,
48
	def process( self, rel_file, src, dst ):
5 by Tim Marston
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
49
50
		# entity is missing in home dir?
16 by Tim Marston
walker now passes Walker.File objects to process(), which includes file name,
51
		if dst.type == '_':
88 by Tim Marston
python3ification
52
			if the.verbose >= 2: print("  _|%s %s" % ( dst.type, rel_file ))
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
53
			if not the.config.ignores.matches( rel_file ):
54
				self.missing.append( rel_file )
5 by Tim Marston
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
55
56
			# if a directory is missing in the home dir, we only really want to
57
			# hear about that and not all the files it contains (which are also
58
			# obviously missing)
59
			return False
60
61
		# entity has changed type?
16 by Tim Marston
walker now passes Walker.File objects to process(), which includes file name,
62
		elif dst.get_type_name() != src.get_type_name():
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
63
64
			# is it a directory that has changed to a symlnik to a directory and
65
			# is an acceptable substitution?
66
			if src.type == 'd' and dst.link_type == 'd' and \
67
					the.config.symlinks.matches( rel_file ):
88 by Tim Marston
python3ification
68
				if the.verbose >= 2: print("  d@d " + rel_file)
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
69
				return True
70
71
			if the.verbose >= 2:
88 by Tim Marston
python3ification
72
				print("  %s|%s %s" % ( dst.type, src.type, rel_file ))
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
73
			if not the.config.ignores.matches( rel_file ):
74
				self.changed.append( "%s (%s => %s)" % (
75
					rel_file, src.get_type_name(), dst.get_type_name() ) )
5 by Tim Marston
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
76
77
			# if an entity has changed to/from a directory, we don't care about
78
			# anything that directory does/did contain
79
			return False
80
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
81
		# entity is a file that has been modified?
16 by Tim Marston
walker now passes Walker.File objects to process(), which includes file name,
82
		if src.type == 'f':
83
			if not filecmp.cmp( src.file, dst.file ):
88 by Tim Marston
python3ification
84
				if the.verbose >= 2: print("  f|f " + rel_file)
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
85
				if not the.config.ignores.matches( rel_file ):
86
					self.modified.append( rel_file )
87
			else:
88 by Tim Marston
python3ification
88
				if the.verbose >= 2: print("  f=f " + rel_file)
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
89
			return False
90
91
		# entity is a symlink that has been modified?
16 by Tim Marston
walker now passes Walker.File objects to process(), which includes file name,
92
		elif dst.type == 'l':
93
			if os.readlink( src.file ) != os.readlink( dst.file ):
88 by Tim Marston
python3ification
94
				if the.verbose >= 2: print("  l|l " + rel_file)
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
95
				if not the.config.ignores.matches( rel_file ):
96
					self.modified.append( rel_file )
97
			else:
88 by Tim Marston
python3ification
98
				if the.verbose >= 2: print("  l=l " + rel_file)
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
99
			return False
100
101
		# TODO: check directory permission changes
5 by Tim Marston
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
102
103
		# nothing to see here
40 by Tim Marston
implemented symlink substitution and ignore list in status walker (and added
104
		if the.verbose >= 2:
88 by Tim Marston
python3ification
105
			print("  %s=%s %s" % ( dst.type, src.type, rel_file ))
5 by Tim Marston
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
106
		return True