bug 1368026, rename observers to observers and stat_observers, r=stas
The `observers` name is now internal to ContentComparer, and
passed in as unconditional list argument to the constructor.
What used to be other_observers is now stat_observers, and
an optional keyword argument.
MozReview-Commit-ID: LN5dCAKKvN3
--- a/compare_locales/commands.py
+++ b/compare_locales/commands.py
@@ -121,16 +121,16 @@ Be careful to specify the right merge di
app = EnumerateApp(config_path, args.l10n_base_dir, args.locales)
configs.append(app.asConfig())
try:
unified_observer = None
if args.unified:
unified_observer = Observer()
observers = compareProjects(
configs,
- other_observer=unified_observer,
+ stat_observer=unified_observer,
merge_stage=args.merge, clobber_merge=args.clobber)
except (OSError, IOError), exc:
print "FAIL: " + str(exc)
self.parser.exit(2)
if args.unified:
return [unified_observer]
return observers
--- a/compare_locales/compare.py
+++ b/compare_locales/compare.py
@@ -147,20 +147,20 @@ class AddRemove(SequenceMatcher):
for item in self.b[j1:j2]:
yield ('add', item)
class Observer(object):
stat_cats = ['missing', 'obsolete', 'missingInFiles', 'report',
'changed', 'unchanged', 'keys']
- def __init__(self, file_stats=False):
+ def __init__(self, filter=None, file_stats=False):
self.summary = defaultdict(lambda: defaultdict(int))
self.details = Tree(dict)
- self.filter = None
+ self.filter = filter
self.file_stats = None
if file_stats:
self.file_stats = defaultdict(lambda: defaultdict(dict))
# support pickling
def __getstate__(self):
state = dict(summary=self._dictify(self.summary), details=self.details)
if self.file_stats is not None:
@@ -345,32 +345,28 @@ class Observer(object):
def __str__(self):
return 'observer'
class ContentComparer:
keyRE = re.compile('[kK]ey')
nl = re.compile('\n', re.M)
- def __init__(self):
+ def __init__(self, observers, stat_observers=None):
'''Create a ContentComparer.
observer is usually a instance of Observer. The return values
of the notify method are used to control the handling of missing
entities.
'''
- self.observers = []
- self.other_observers = []
+ self.observers = observers
+ if stat_observers is None:
+ stat_observers = []
+ self.stat_observers = stat_observers
self.merge_stage = None
- def add_observer(self, obs):
- '''Add a non-filtering observer.
- Results from the notify calls are ignored.
- '''
- self.other_observers.append(obs)
-
def set_merge_stage(self, merge_stage):
self.merge_stage = merge_stage
def merge(self, ref_entities, ref_map, ref_file, l10n_file, missing,
skips, ctx, canMerge, encoding):
outfile = mozpath.join(self.merge_stage, l10n_file.module,
l10n_file.file)
outdir = mozpath.dirname(outfile)
@@ -406,38 +402,38 @@ class ContentComparer:
return s + '\n'
return s
f.write(''.join(map(ensureNewline, trailing)))
f.close()
def notify(self, category, file, data):
"""Check observer for the found data, and if it's
- not to ignore, notify other_observers.
+ not to ignore, notify stat_observers.
"""
rvs = set(
observer.notify(category, file, data)
for observer in self.observers
)
if all(rv == 'ignore' for rv in rvs):
return 'ignore'
rvs.discard('ignore')
- for obs in self.other_observers:
- # non-filtering other_observers, ignore results
+ for obs in self.stat_observers:
+ # non-filtering stat_observers, ignore results
obs.notify(category, file, data)
if 'error' in rvs:
return 'error'
assert len(rvs) == 1
return rvs.pop()
def updateStats(self, file, stats):
"""Check observer for the found data, and if it's
- not to ignore, notify other_observers.
+ not to ignore, notify stat_observers.
"""
- for observer in self.observers + self.other_observers:
+ for observer in self.observers + self.stat_observers:
observer.updateStats(file, stats)
def remove(self, obsolete):
self.notify('obsoleteFile', obsolete, None)
pass
def compare(self, ref_file, l10n, extra_tests=None):
try:
@@ -573,28 +569,30 @@ class ContentComparer:
# overload this if needed
pass
def doChanged(self, file, ref_entity, l10n_entity):
# overload this if needed
pass
-def compareProjects(project_configs, other_observer=None,
+def compareProjects(project_configs, stat_observer=None,
file_stats=False,
merge_stage=None, clobber_merge=False):
- comparer = ContentComparer()
- if other_observer is not None:
- comparer.add_observer(other_observer)
locales = set()
+ observers = []
for project in project_configs:
- observer = Observer(file_stats=file_stats)
- observer.filter = project.filter
- comparer.observers.append(observer)
+ observers.append(
+ Observer(filter=project.filter, file_stats=file_stats))
locales.update(project.locales)
+ if stat_observer is not None:
+ stat_observers = [stat_observer]
+ else:
+ stat_observers = None
+ comparer = ContentComparer(observers, stat_observers=stat_observers)
for locale in sorted(locales):
files = paths.ProjectFiles(locale, *project_configs)
if merge_stage is not None:
mergedir = merge_stage.format(ab_CD=locale)
comparer.set_merge_stage(mergedir)
if clobber_merge:
modules = set(_m.get('module') for _m in files.matchers)
modules.discard(None)
@@ -616,9 +614,9 @@ def compareProjects(project_configs, oth
module=module, locale=locale)
if not os.path.exists(l10npath):
comparer.add(reffile, l10n)
continue
if not os.path.exists(refpath):
comparer.remove(l10n)
continue
comparer.compare(reffile, l10n, extra_tests)
- return comparer.observers
+ return observers
--- a/compare_locales/tests/test_merge.py
+++ b/compare_locales/tests/test_merge.py
@@ -41,18 +41,17 @@ class TestProperties(unittest.TestCase,
self.assertTrue(os.path.isdir(self.tmp))
self.reference("""foo = fooVal
bar = barVal
eff = effVal""")
self.localized("""foo = lFoo
bar = lBar
eff = lEff
""")
- cc = ContentComparer()
- cc.observers.append(Observer())
+ cc = ContentComparer([Observer()])
cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
cc.compare(File(self.ref, "en-reference.properties", ""),
File(self.l10n, "l10n.properties", ""))
self.assertDictEqual(
cc.observers[0].toJSON(),
{'summary':
{None: {
'changed': 3
@@ -65,18 +64,17 @@ eff = lEff
def testMissing(self):
self.assertTrue(os.path.isdir(self.tmp))
self.reference("""foo = fooVal
bar = barVal
eff = effVal""")
self.localized("""bar = lBar
""")
- cc = ContentComparer()
- cc.observers.append(Observer())
+ cc = ContentComparer([Observer()])
cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
cc.compare(File(self.ref, "en-reference.properties", ""),
File(self.l10n, "l10n.properties", ""))
self.assertDictEqual(
cc.observers[0].toJSON(),
{'summary':
{None: {
'changed': 1, 'missing': 2
@@ -100,18 +98,17 @@ eff = effVal""")
self.assertTrue(os.path.isdir(self.tmp))
self.reference("""foo = fooVal
bar = %d barVal
eff = effVal""")
self.localized("""\
bar = %S lBar
eff = leffVal
""")
- cc = ContentComparer()
- cc.observers.append(Observer())
+ cc = ContentComparer([Observer()])
cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
cc.compare(File(self.ref, "en-reference.properties", ""),
File(self.l10n, "l10n.properties", ""))
self.assertDictEqual(
cc.observers[0].toJSON(),
{'summary':
{None: {
'changed': 2, 'errors': 1, 'missing': 1
@@ -138,18 +135,17 @@ eff = leffVal
def testObsolete(self):
self.assertTrue(os.path.isdir(self.tmp))
self.reference("""foo = fooVal
eff = effVal""")
self.localized("""foo = fooVal
other = obsolete
eff = leffVal
""")
- cc = ContentComparer()
- cc.observers.append(Observer())
+ cc = ContentComparer([Observer()])
cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
cc.compare(File(self.ref, "en-reference.properties", ""),
File(self.l10n, "l10n.properties", ""))
self.assertDictEqual(
cc.observers[0].toJSON(),
{'summary':
{None: {
'changed': 1, 'obsolete': 1, 'unchanged': 1
@@ -178,18 +174,17 @@ class TestDTD(unittest.TestCase, Content
self.assertTrue(os.path.isdir(self.tmp))
self.reference("""<!ENTITY foo 'fooVal'>
<!ENTITY bar 'barVal'>
<!ENTITY eff 'effVal'>""")
self.localized("""<!ENTITY foo 'lFoo'>
<!ENTITY bar 'lBar'>
<!ENTITY eff 'lEff'>
""")
- cc = ContentComparer()
- cc.observers.append(Observer())
+ cc = ContentComparer([Observer()])
cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
cc.compare(File(self.ref, "en-reference.dtd", ""),
File(self.l10n, "l10n.dtd", ""))
self.assertDictEqual(
cc.observers[0].toJSON(),
{'summary':
{None: {
'changed': 3
@@ -202,18 +197,17 @@ class TestDTD(unittest.TestCase, Content
def testMissing(self):
self.assertTrue(os.path.isdir(self.tmp))
self.reference("""<!ENTITY foo 'fooVal'>
<!ENTITY bar 'barVal'>
<!ENTITY eff 'effVal'>""")
self.localized("""<!ENTITY bar 'lBar'>
""")
- cc = ContentComparer()
- cc.observers.append(Observer())
+ cc = ContentComparer([Observer()])
cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
cc.compare(File(self.ref, "en-reference.dtd", ""),
File(self.l10n, "l10n.dtd", ""))
self.assertDictEqual(
cc.observers[0].toJSON(),
{'summary':
{None: {
'changed': 1, 'missing': 2
@@ -237,18 +231,17 @@ class TestDTD(unittest.TestCase, Content
self.assertTrue(os.path.isdir(self.tmp))
self.reference("""<!ENTITY foo 'fooVal'>
<!ENTITY bar 'barVal'>
<!ENTITY eff 'effVal'>""")
self.localized("""<!ENTITY foo 'fooVal'>
<!ENTY bar 'gimmick'>
<!ENTITY eff 'effVal'>
""")
- cc = ContentComparer()
- cc.observers.append(Observer())
+ cc = ContentComparer([Observer()])
cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
cc.compare(File(self.ref, "en-reference.dtd", ""),
File(self.l10n, "l10n.dtd", ""))
self.assertDictEqual(
cc.observers[0].toJSON(),
{'summary':
{None: {
'errors': 1, 'missing': 1, 'unchanged': 2