~ubuntu-branches/ubuntu/lucid/firefox/lucid-updates

« back to all changes in this revision

Viewing changes to debian/compare-locales/lib/Mozilla/CompareLocales.py

  • Committer: Package Import Robot
  • Author(s): Chris Coulson, Chris Coulson, Jamie Strandboge
  • Date: 2012-06-01 18:33:36 UTC
  • mfrom: (1.1.43)
  • Revision ID: package-import@ubuntu.com-20120601183336-bamdjl485ei371rz
Tags: 13.0+build1-0ubuntu0.10.04.1
* New upstream stable release (FIREFOX_13_0_BUILD1)
  - see LP: #1007495 for USN information

[ Chris Coulson <chris.coulson@canonical.com> ]
* Refresh build-depends:
  - Bump minimum GTK version to 2.14 as we build with GIO support
  - Add minimum requirement for glib (2.18)
  - Drop libidl-dev, this doesn't appear to be needed now
  - Bump minimum NSPR version to 4.9.0 for --enable-system-nspr builds
  - Bump minimum sqlite version to 3.7.10 for --enable-system-sqlite
    builds
  - Bump minimum NSS version to 3.13.2 for --enable-system-nss builds
* Refresh patches:
  - update debian/patches/ubuntu-ua-string-changes.patch
  - update debian/patches/ubuntu-codes-google.patch
  - update debian/patches/use-new-yasm-in-lucid.patch
  - update debian/patches/firefox-kde.patch
  - update debian/patches/mozilla-kde.patch
  - update debian/patches/dont-include-hyphenation-patterns.patch
* Clean up the file exclude list and add comments for excluded files
  - update debian/build/create-tarball.py
* Make it easy to run Firefox in valgrind for builds that are compiled
  with explicit valgrind support
  - update debian/firefox.sh.in
* Don't build with gnomevfs anymore
  - update debian/firefox-gnome-support.install.in
  - update debian/config/mozconfig.in
  - update debian/control.in
  - update debian/rules
* Bump debhelper compat to 7
  - update debian/apport/blacklist.in
  - update debian/apport/source_firefox.py.in
  - update debian/compat
  - update debian/config/mozconfig.in
  - update debian/control.in
  - update debian/firefox-dev.install.in
  - update debian/firefox-dev.links.in
  - update debian/firefox-gnome-support.install.in
  - update debian/firefox.dirs.in
  - update debian/firefox.install.in
  - update debian/firefox.links.in
  - update debian/firefox.postinst.in
  - update debian/firefox.preinst.in
  - update debian/firefox.sh.in
  - update debian/pkgconfig/libxul.pc.in
  - update debian/pkgconfig/mozilla-nspr.pc.in
  - update debian/pkgconfig/mozilla-plugin.pc.in
  - update debian/rules
  - update debian/usr.bin.firefox.apparmor.10.04
  - update debian/usr.bin.firefox.apparmor.9.10
* Override 2 embedded-library lintian errors
  - update debian/firefox.lintian-overrides.in
* Drop debian/patches/distro-locale-searchplugins after landing of
  bmo: #515232
* Don't hardcode general.useragent.locale to en-US, now that it's used
  for searchplugin localization. This means we can drop this pref from
  ubufox
  - add debian/patches/dont-override-general-useragent-locale.patch
  - update debian/patches/series
* Drop patches fixed upstream
  - remove debian/patches/no-sps-profiler-on-unsupported-archs.patch
  - remove debian/patches/avoid-dbus-roundtrip-for-httpchannel.patch
  - update debian/patches/series
* Apport hook improvements:
  - Add support for reporting preference defaults that are set by extensions
  - When reporting preferences, record the source of each preference
  - Report plugin packages for plugins that are installed with the
    package manager
  - Add some addon manager related prefs to the whitelist
  - Display additional metadata in the extensions report
  - Take "default-to-compatible" in to account when determining whether
    the user is running incompatible addons
  - Attach submitted crash ID's to bug reports
  - Report if files in the profile folder have broken permissions
* Update compare-locales to 0.9.5
* Fix make-makefile test failure when the build directory contains
  perl regexp control characters
  - add debian/patches/make-makefile-test-fix.patch
  - update debian/patches/series
* Fix for NSS libs not being signed, breaking FIPS
  - update debian/rules

[ Jamie Strandboge <jamie@ubuntu.com> ]
* adjust apparmor profile to deny reads to @{PROC}/[0-9]*/net/dev. Patch 
  thanks to James Troup (LP: #955066)
* adjust apparmor profile to deny reads to @{PROC}/[0-9]*/net/wireless.
  Patch thanks to James Troup (LP: #974141)

Show diffs side-by-side

added added

removed removed

Lines of Context:
65
65
        return True
66
66
    return False
67
67
 
 
68
try:
 
69
  from json import dumps
 
70
except:
 
71
  from simplejson import dumps
 
72
 
68
73
 
69
74
import Parser
70
75
import Paths
 
76
import Checks
71
77
 
72
78
class Tree(object):
73
79
  def __init__(self, valuetype):
270
276
      except KeyError:
271
277
        self.details[file][category] = [data]
272
278
      self.summary[file.locale]['errors'] += 1
 
279
    elif category == 'warning':
 
280
      try:
 
281
        self.details[file][category].append(data)
 
282
      except KeyError:
 
283
        self.details[file][category] = [data]
 
284
      self.summary[file.locale]['warnings'] += 1
273
285
    return rv
 
286
  def toExhibit(self):
 
287
    items = []
 
288
    for locale in sorted(self.summary.iterkeys()):
 
289
      summary = self.summary[locale]
 
290
      if locale is not None:
 
291
        item = {'id': 'xxx/' + locale,
 
292
                'label': locale,
 
293
                'locale': locale}
 
294
      else:
 
295
        item = {'id': 'xxx',
 
296
                'label': 'xxx',
 
297
                'locale': 'xxx'}
 
298
      item['type'] = 'Build'
 
299
      total = sum([summary[k]
 
300
                   for k in ('changed','unchanged','report','missing',
 
301
                             'missingInFiles')
 
302
                   if k in summary])
 
303
      rate = (('changed' in summary and summary['changed'] * 100)
 
304
              or 0) / total
 
305
      item.update((k, summary.get(k, 0))
 
306
                  for k in ('changed','unchanged'))
 
307
      item.update((k, summary[k]) 
 
308
                  for k in ('report','errors','warnings')
 
309
                  if k in summary)
 
310
      item['missing'] = summary.get('missing', 0) + \
 
311
          summary.get('missingInFiles', 0)
 
312
      item['completion'] = rate
 
313
      item['total'] = total
 
314
      result = 'success'
 
315
      if item.get('warnings',0):
 
316
        result = 'warning'
 
317
      if item.get('errors',0) or item.get('missing',0):
 
318
        result = 'failure'
 
319
      item['result'] = result
 
320
      items.append(item)
 
321
    data = {"properties": dict.fromkeys(
 
322
        ("completion", "errors", "warnings", "missing", "report",
 
323
         "unchanged", "changed", "obsolete"),
 
324
        {"valueType": "number"}),
 
325
              "types": {
 
326
        "Build": {"pluralLabel": "Builds"}
 
327
        }}
 
328
    data['items'] = items
 
329
    return dumps(data, indent=2)
274
330
  def serialize(self, type="text/plain"):
 
331
    if type=="application/json":
 
332
      return self.toExhibit()
275
333
    def tostr(t):
276
334
      if t[1] == 'key':
277
335
        return '  ' * t[0] + '/'.join(t[2])
279
337
      indent = '  ' * (t[0] + 1)
280
338
      if 'error' in t[2]:
281
339
        o += [indent + 'ERROR: ' + e for e in t[2]['error']]
 
340
      if 'warning' in t[2]:
 
341
        o += [indent + 'WARNING: ' + e for e in t[2]['warning']]
282
342
      if 'missingEntity' in t[2] or 'obsoleteEntity' in t[2]:
283
343
        missingEntities = ('missingEntity' in t[2] and t[2]['missingEntity']) \
284
344
            or []
314
374
 
315
375
class ContentComparer:
316
376
  keyRE = re.compile('[kK]ey')
 
377
  nl = re.compile('\n', re.M)
317
378
  def __init__(self, filterObserver):
318
379
    '''Create a ContentComparer.
319
380
    filterObserver is usually a instance of Observer. The return values
331
392
    self.observers.append(obs)
332
393
  def set_merge_stage(self, merge_stage):
333
394
    self.merge_stage = merge_stage
334
 
  def merge(self, ref_entities, ref_map, ref_file, l10n_file, missing, p):
 
395
  def merge(self, ref_entities, ref_map, ref_file, l10n_file, missing, skips,
 
396
            p):
335
397
    outfile = os.path.join(self.merge_stage, l10n_file.module, l10n_file.file)
336
398
    outdir = os.path.dirname(outfile)
337
399
    if not os.path.isdir(outdir):
340
402
      shutil.copyfile(ref_file.fullpath, outfile)
341
403
      print "copied reference to " + outfile
342
404
      return
343
 
    trailing = [ref_entities[ref_map[key]].all for key in missing]
344
 
    shutil.copyfile(l10n_file.fullpath, outfile)
 
405
    trailing = (['\n'] + 
 
406
                [ref_entities[ref_map[key]].all for key in missing] +
 
407
                [ref_entities[ref_map[skip.key]].all for skip in skips])
 
408
    if skips:
 
409
      # we need to skip a few errornous blocks in the input, copy by hand
 
410
      f = codecs.open(outfile, 'wb', p.encoding)
 
411
      offset = 0
 
412
      for skip in skips:
 
413
        chunk = skip.span
 
414
        f.write(p.contents[offset:chunk[0]])
 
415
        offset = chunk[1]
 
416
      f.write(p.contents[offset:])
 
417
    else:
 
418
      shutil.copyfile(l10n_file.fullpath, outfile)
 
419
      f = codecs.open(outfile, 'ab', p.encoding)
345
420
    print "adding to " + outfile
346
 
    f = codecs.open(outfile, 'ab', p.encoding)
347
 
    f.write(''.join(trailing))
 
421
    def ensureNewline(s):
 
422
      if not s.endswith('\n'):
 
423
        return s + '\n'
 
424
      return s
 
425
    f.write(''.join(map(ensureNewline,trailing)))
348
426
    f.close()
349
427
  def notify(self, category, file, data):
350
 
    '''Check filterObserver for the found data, and if it's
 
428
    """Check filterObserver for the found data, and if it's
351
429
    not to ignore, notify observers.
352
 
    '''
 
430
    """
353
431
    rv = self.filterObserver.notify(category, file, data)
354
432
    if rv == 'ignore':
355
433
      return rv
363
441
  def compare(self, ref_file, l10n):
364
442
    try:
365
443
      p = Parser.getParser(ref_file.file)
 
444
      checks = Checks.getChecks(ref_file)
366
445
    except UserWarning:
367
446
      # no comparison, XXX report?
368
447
      return
383
462
    except Exception, e:
384
463
      self.notify('error', l10n, str(e))
385
464
      return
 
465
    lines = []
 
466
    def _getLine(offset):
 
467
      if not lines:
 
468
        lines.append(0)
 
469
        for m in self.nl.finditer(p.contents):
 
470
          lines.append(m.end())
 
471
      _line = 1
 
472
      for i in xrange(len(lines), 0, -1):
 
473
        if offset >= lines[i-1]:
 
474
          return (i, offset - lines[i-1])
 
475
      return (1, offset)
386
476
    l10n_list = l10n_map.keys()
387
477
    l10n_list.sort()
388
478
    ar = AddRemove()
390
480
    ar.set_right(l10n_list)
391
481
    report = missing = obsolete = changed = unchanged = keys = 0
392
482
    missings = []
 
483
    skips = []
393
484
    for action, item_or_pair in ar:
394
485
      if action == 'delete':
395
486
        # missing entity
414
505
      else:
415
506
        # entity found in both ref and l10n, check for changed
416
507
        entity = item_or_pair[0]
 
508
        refent = ref[0][ref[1][entity]]
 
509
        l10nent = l10n_entities[l10n_map[entity]]
417
510
        if self.keyRE.search(entity):
418
511
          keys += 1
419
512
        else:
420
 
          refent = ref[0][ref[1][entity]]
421
 
          l10nent = l10n_entities[l10n_map[entity]]
422
513
          if refent.val == l10nent.val:
423
514
            self.doUnchanged(l10nent)
424
515
            unchanged += 1
425
516
          else:
426
517
            self.doChanged(ref_file, refent, l10nent)
427
518
            changed += 1
 
519
          # run checks:
 
520
        if checks:
 
521
          for tp, pos, msg, cat in checks(refent, l10nent):
 
522
            # compute real src position, if first line, col needs adjustment
 
523
            _l, _offset = _getLine(l10nent.val_span[0])
 
524
            if isinstance(pos, tuple):
 
525
              # line, column
 
526
              if pos[0] == 1:
 
527
                col = pos[1] + _offset
 
528
              else:
 
529
                col = pos[1]
 
530
              _l += pos[0] - 1
 
531
            else:
 
532
              _l, col = _getLine(l10nent.val_span[0] + pos)
 
533
             # skip error entities when merging
 
534
            if tp == 'error' and self.merge_stage is not None:
 
535
              skips.append(l10nent)
 
536
            self.notify(tp, l10n,
 
537
                        u"%s at line %d, column %d for %s" %
 
538
                        (msg, _l, col, refent.key))
428
539
        pass
429
540
    if missing:
430
541
      self.notify('missing', l10n, missing)
431
 
      if self.merge_stage is not None and missings:
432
 
        self.merge(ref[0], ref[1], ref_file, l10n, missings, p)
 
542
    if self.merge_stage is not None and (missings or skips):
 
543
      self.merge(ref[0], ref[1], ref_file, l10n, missings, skips, p)
433
544
    if report:
434
545
      self.notify('report', l10n, report)
435
546
    if obsolete:
464
575
    # overload this if needed
465
576
    pass
466
577
 
467
 
def compareApp(app, otherObserver = None, merge_stage = None):
 
578
def compareApp(app, otherObserver = None, merge_stage = None, clobber = False):
468
579
  '''Compare locales set in app.
469
580
 
470
581
  Optional arguments are:
473
584
    The return values of that callback are ignored.
474
585
  - merge_stage. A directory to be used for staging the output of
475
586
    l10n-merge.
 
587
  - clobber. Clobber the module subdirectories of the merge dir as we go.
 
588
    Use wisely, as it might cause data loss.
476
589
  '''
477
590
  o  = Observer()
478
591
  cc = ContentComparer(o)
481
594
  cc.set_merge_stage(merge_stage)
482
595
  o.filter = app.filter
483
596
  for module, reference, locales in app:
 
597
    if merge_stage is not None and clobber:
 
598
      # if clobber and merge is on, remove the stage for the module if it exists
 
599
      clobberdir = os.path.join(merge_stage, module)
 
600
      if os.path.exists(clobberdir):
 
601
        shutil.rmtree(clobberdir)
 
602
        print "clobbered " + clobberdir
484
603
    dc = DirectoryCompare(reference)
485
604
    dc.setWatcher(cc)
486
605
    for locale, localization in locales: