7185135 i18n messages should use parameterized values
7188804 pkg5 should depend on gnu-gettext
7194773 pkg.mo should move to pkg:/package/pkg
--- a/.hgignore Wed Oct 31 10:48:34 2012 -0700
+++ b/.hgignore Fri Nov 02 11:42:49 2012 +1300
@@ -34,6 +34,7 @@
^src/gui/help/package-manager-__LOCALE__.omf$
^src/pkg/Makefile.link
^src/pkg/pkgtmp/
+^src/po/i18n_errs.txt$
^src/po/pkg.pot$
^src/tests/.coverage$
^src/tests/.coverage-.*$
--- a/src/client.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/client.py Fri Nov 02 11:42:49 2012 +1300
@@ -1372,7 +1372,8 @@
api_inst.execute_plan()
rval = EXIT_OK
except RuntimeError, e:
- error(_("%s failed: %s") % (operation, e))
+ error(_("%(operation)s failed: %(err)s") %
+ {"operation": operation, "err": e})
rval = EXIT_OOPS
except (api_errors.InvalidPlanError,
api_errors.ActionExecutionError,
@@ -1382,8 +1383,8 @@
error("\n" + str(e))
rval = EXIT_OOPS
except (api_errors.LinkedImageException), e:
- error(_("%s failed (linked image exception(s)):\n%s") %
- (operation, str(e)))
+ error(_("%(operation)s failed (linked image exception(s)):\n"
+ "%(err)s") % {"operation": operation, "err": e})
rval = e.lix_exitrv
except api_errors.ImageUpdateOnLiveImageException:
error(_("%s cannot be done on live image") % operation)
@@ -1421,7 +1422,8 @@
rval = EXIT_OOPS
except Exception, e:
error(_("An unexpected error happened during "
- "%s: %s") % (operation, e))
+ "%(operation)s: %(err)s") %
+ {"operation": operation, "err": e})
raise
finally:
exc_type = exc_value = exc_tb = None
@@ -1491,12 +1493,12 @@
error(_("No image rooted at '%s'") % e.user_dir, cmd=op)
return EXIT_OOPS
if e_type == api_errors.InventoryException:
- error("\n" + _("%s failed (inventory exception):\n%s") % (op,
- e))
+ error("\n" + _("%(operation)s failed (inventory exception):\n"
+ "%(err)s") % {"operation": op, "err": e})
return EXIT_OOPS
if isinstance(e, api_errors.LinkedImageException):
- error(_("%s failed (linked image exception(s)):\n%s") %
- (op, str(e)))
+ error(_("%(operation)s failed (linked image exception(s)):\n"
+ "%(err)s") % {"operation": op, "err": e})
return e.lix_exitrv
if e_type == api_errors.IpkgOutOfDateException:
msg(_("""\
@@ -2104,12 +2106,14 @@
v = int(v)
except (ValueError, TypeError):
# not a valid integer
- err = _("invalid '%s' value: %s") % (k, v)
+ err = _("invalid '%(opt)s' value: %(val)s") % \
+ {"opt": k, "val": v}
usage(err, cmd=op)
# check the minimum bounds
if minimum is not None and v < minimum:
- err = _("'%s' must be >= %d") % (k, minimum)
+ err = _("'%(opt)s' must be >= %(minimum)d") % \
+ {"opt": k, "minimum": minimum}
usage(err, cmd=op)
# update the new options array to make the value an integer
@@ -2118,7 +2122,8 @@
def opts_cb_fd(k, op, api_inst, opts, opts_new):
opts_cb_int(k, op, api_inst, opts, opts_new, minimum=0)
- err = _("invalid '%s' value: %s") % (k, opts_new[k])
+ err = _("invalid '%(opt)s' value: %(optval)s") % \
+ {"opt": k, "optval": opts_new[k]}
try:
os.fstat(opts_new[k])
except OSError:
@@ -2519,8 +2524,8 @@
# make sure the user didn't specify duplicate variants
if name in variants:
- usage(_("%s: duplicate variant specified: %s") %
- (op, name))
+ usage(_("%(subcmd)s: duplicate variant specified: "
+ "%(variant)s") % {"subcmd": op, "variant": name})
variants[name] = value
return __api_op(op, api_inst, _accept=accept, _li_ignore=li_ignore,
@@ -2983,8 +2988,10 @@
for a in api_inst.get_avoid_list():
tracking = " ".join(a[1])
if tracking:
- logger.info(_(" %s (group dependency of '%s')")
- % (a[0], tracking))
+ logger.info(_(
+ " %(avoid_pkg)s (group dependency of "
+ "'%(tracking_pkg)s')")
+ % {"avoid_pkg": a[0], "tracking_pkg": tracking})
else:
logger.info(" %s" % a[0])
@@ -4043,8 +4050,8 @@
total = cre.total
succeeded = cre.succeeded
- txt = _("pkg: %s/%s catalogs successfully updated:") % (succeeded,
- total)
+ txt = _("pkg: %(succeeded)s/%(total)s catalogs successfully "
+ "updated:") % {"succeeded": succeeded, "total": total}
if cre.failed:
# This ensures that the text gets printed before the errors.
logger.error(txt)
@@ -6609,7 +6616,8 @@
__ret = handle_errors(_wrapper, non_wrap_print=False)
s = ""
if __ret == 99:
- s += _("\n%s%s") % (__e, traceback_str)
+ s += _("\n%(err)s%(stacktrace)s") % \
+ {"err": __e, "stacktrace": traceback_str}
s += _("\n\nDespite the error while indexing, the operation "
"has completed successfuly.")
--- a/src/modules/actions/depend.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/actions/depend.py Fri Nov 02 11:42:49 2012 +1300
@@ -178,9 +178,10 @@
if required and pkgdefs.PKG_STATE_OBSOLETE in \
image.get_pkg_state(installed_version):
errors.append(
- _("%s dependency on an obsolete package (%s);"
- "this package must be uninstalled manually") %
- (ctype, installed_version))
+ _("%(dep_type)s dependency on an obsolete package "
+ "(%(obs_pkg)s); this package must be uninstalled "
+ "manually") %
+ {"dep_type": ctype, "obs_pkg": installed_version})
return errors
return errors
--- a/src/modules/altroot.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/altroot.py Fri Nov 02 11:42:49 2012 +1300
@@ -110,8 +110,8 @@
# we're going to update root and path so prepare an error
# message with the existing values now.
- eremote = _("Path outside alternate root: root=%s, path=%s") % \
- (root, path)
+ eremote = _("Path outside alternate root: root=%(root)s, "
+ "path=%(path)s") % {"root": root, "path": path}
# make target into a relative path
if os.path.isabs(path):
--- a/src/modules/client/api_errors.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/client/api_errors.py Fri Nov 02 11:42:49 2012 +1300
@@ -550,10 +550,11 @@
res += [ s % p for p in self.illegal ]
if self.badarch:
- s = _("'%s' supports the following architectures: %s")
+ s = _("'%(p)s' supports the following architectures: "
+ "%(archs)s")
a = _("Image architecture is defined as: %s")
- res += [ s % (self.badarch[0],
- ", ".join(self.badarch[1]))]
+ res += [ s % {"p": self.badarch[0],
+ "archs": ", ".join(self.badarch[1])}]
res += [ a % (self.badarch[2])]
s = _("'%(p)s' depends on obsolete package '%(op)s'")
@@ -806,8 +807,8 @@
for pkg in sorted(pkglist):
s += _(" %s\n") % pkg
else:
- t = _(" %d packages deliver '%s', including:\n")
- s += t % (num, action)
+ t = _(" %(n)d packages deliver '%(a)s', including:\n")
+ s += t % {"n": num, "a": action}
for pkg in sorted(pkglist)[:5]:
s += _(" %s\n") % pkg
@@ -1453,7 +1454,8 @@
def __str__(self):
if self.location:
return _("Error encountered while retrieving data from "
- "'%s':\n%s") % (self.location, self.data)
+ "'%(location)s':\n%(data)s") % \
+ {"location": self.location, "data": self.data}
return _("Error encountered while retrieving data from: %s") % \
self.data
--- a/src/modules/client/bootenv.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/client/bootenv.py Fri Nov 02 11:42:49 2012 +1300
@@ -587,9 +587,9 @@
self.img.history.log_operation_error(error=e)
raise e
- logger.error(_("%s failed to be updated. No changes "
- "have been made to %s.") % (self.be_name,
- self.be_name))
+ logger.error(_("%(bename)s failed to be updated. No "
+ "changes have been made to %(bename)s.") %
+ {"bename": self.be_name})
def destroy_snapshot(self):
@@ -655,10 +655,11 @@
self.destroy_snapshot()
- logger.error(_("The Boot Environment %s failed to be "
- "updated. A snapshot was taken before the failed "
- "attempt and has been restored so no changes have "
- "been made to %s.") % (self.be_name, self.be_name))
+ logger.error(_("The Boot Environment %(bename)s failed "
+ "to be updated. A snapshot was taken before the "
+ "failed attempt and has been restored so no "
+ "changes have been made to %(bename)s.") %
+ {"bename": self.be_name})
def activate_install_uninstall(self):
"""Activate an install/uninstall attempt. Which just means
--- a/src/modules/client/image.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/client/image.py Fri Nov 02 11:42:49 2012 +1300
@@ -361,8 +361,9 @@
"""A list of strings decribing errors encountered while parsing
trust anchors."""
- return [_("%s is expected to be a certificate but could not be "
- "parsed. The error encountered was:\n\t%s") % (p, e)
+ return [_("%(path)s is expected to be a certificate but could "
+ "not be parsed. The error encountered was:\n\t%(err)s") %
+ {"path": p, "err": e}
for p, e in self.__bad_trust_anchors
]
--- a/src/modules/client/pkg_solver.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/client/pkg_solver.py Fri Nov 02 11:42:49 2012 +1300
@@ -1711,7 +1711,10 @@
tag = _("Reason:")
if fmri in already_seen:
- reason = _("%s %s [already rejected; see above]") % (indent, tag)
+ # note to translators: 'indent' will be a series of
+ # whitespaces.
+ reason = _("%(indent)s %(tag)s [already rejected; "
+ "see above]") % {"indent": indent, "tag": tag}
return fmri_id, [reason]
already_seen.add(fmri)
--- a/src/modules/client/progress.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/client/progress.py Fri Nov 02 11:42:49 2012 +1300
@@ -450,9 +450,12 @@
# See if we indeed met our goal.
if goalcheck and not self.metgoal():
- exstr = _("Goal mismatch '%s': "
- "expected goal: %s, current value: %s") % \
- (self.name, str(self.goalitems), str(self.items))
+ exstr = _("Goal mismatch '%(name)s': "
+ "expected goal: %(expected)s, "
+ "current value: %(current)s") % \
+ {"name": self.name,
+ "expected": self.goalitems,
+ "current": self.items}
logger.error("\n" + exstr)
assert self.metgoal(), exstr
@@ -1751,8 +1754,15 @@
if self.major_phase == self.PHASE_UTILITY:
return ""
- return _("%*s: ") % (self.phase_max_width,
- self.phase_names[self.major_phase])
+ # The following string was originally expressed as
+ # "%*s: " % \
+ # (self.phase_max_width, self.phase_names[self.major_phase])
+ # however xgettext incorrectly flags this as an improper use of
+ # non-parameterized messages, which gets detected as an error
+ # during our build. So instead, we express the string using
+ # an equivalent <str>.format(..) function
+ s = _("{phase:>%d}: ") % self.phase_max_width
+ return s.format(phase=self.phase_names[self.major_phase])
#
# Helper routines
@@ -1859,8 +1869,10 @@
# adjusts the output based on the major phase.
#
self._pe.cprint(self._phase_prefix() +
- _("Fetching manifests: %s %d%% complete") %
- (self.mfst_fetch.pair(), self.mfst_fetch.pctdone()))
+ _("Fetching manifests: %(num)s %(pctcomplete)d%% "
+ "complete") %
+ {"num": self.mfst_fetch.pair(),
+ "pctcomplete": self.mfst_fetch.pctdone()})
def _mfst_commit(self, outspec):
# For now, manifest commit is hard to handle in this
@@ -1906,15 +1918,19 @@
mbs = format_pair("%.1f", self.dl_bytes.items,
self.dl_bytes.goalitems, scale=(1024 * 1024))
self._pe.cprint(
- _("Download: %s items %sMB %d%% complete %s") %
- (self.dl_files.pair(), mbs, self.dl_bytes.pctdone(),
- speedstr))
+ _("Download: %(num)s items %(mbs)sMB "
+ "%(pctcomplete)d%% complete %(speed)s") %
+ {"num": self.dl_files.pair(), "mbs": mbs,
+ "pctcomplete": self.dl_bytes.pctdone(),
+ "speed": speedstr})
else:
# 'last'
goal = misc.bytes_to_str(self.dl_bytes.goalitems)
self.__generic_done(
- msg=_("Download: Completed %s in %.2f seconds %s") %
- (goal, self.dl_estimator.elapsed(), speedstr))
+ msg=_("Download: Completed %(num)s in %(sec).2f "
+ "seconds %(speed)s") %
+ {"num": goal, "sec": self.dl_estimator.elapsed(),
+ "speed": speedstr})
def _republish_output(self, outspec):
if "startpkg" in outspec.changed:
@@ -1934,16 +1950,18 @@
if outspec.last:
goal = misc.bytes_to_str(self.archive_bytes.goalitems)
self.__generic_done(
- msg=_("Archiving: Completed %s in %.2f seconds") %
- (goal, self.archive_items.elapsed()))
+ msg=_("Archiving: Completed %(num)s in %(secs).2f "
+ "seconds") %
+ {"num": goal, "secs": self.archive_items.elapsed()})
return
mbs = format_pair("%.1f", self.archive_bytes.items,
self.archive_bytes.goalitems, scale=(1024 * 1024))
self._pe.cprint(
- _("Archiving: %s items %sMB %d%% complete") %
- (self.archive_items.pair(), mbs,
- self.archive_bytes.pctdone()))
+ _("Archiving: %(pair)s items %(mbs)sMB %(pctcomplete)d%% "
+ "complete") %
+ {"pair": self.archive_items.pair(), "mbs": mbs,
+ "pctcomplete": self.archive_bytes.pctdone()})
#
# The progress tracking infrastructure wants to tell us about each
@@ -1960,9 +1978,10 @@
sum(x.items for x in self._actionitems.values())
total_goal = \
sum(x.goalitems for x in self._actionitems.values())
- self._pe.cprint(self._phase_prefix() + _("%s actions (%s)") %
- (format_pair("%d", total_actions, total_goal),
- actionitem.name))
+ self._pe.cprint(self._phase_prefix() +
+ _("%(num)s actions (%(type)s)") %
+ {"num": format_pair("%d", total_actions, total_goal),
+ "type": actionitem.name})
def _act_output_all_done(self):
total_goal = \
@@ -1972,8 +1991,9 @@
if total_goal == 0:
return
self._pe.cprint(self._phase_prefix() +
- _("Completed %d actions in %.2f seconds.") %
- (total_goal, total_time))
+ _("Completed %(numactions)d actions in %(time).2f "
+ "seconds.") %
+ {"numactions": total_goal, "time": total_time})
def _job_output(self, outspec, jobitem):
if outspec.first:
@@ -2034,9 +2054,11 @@
return
running = " ".join([str(i) for i in self.linked_running])
- msg = _("Linked images: %s done; %d working: %s") % \
- (format_pair("%d", done, self.linked_total),
- len(self.linked_running), running)
+ msg = _("Linked images: %(pair)s done; %(numworking)d working: "
+ "%(running)s") % \
+ {"pair": format_pair("%d", done, self.linked_total),
+ "numworking": len(self.linked_running),
+ "running": running}
self._pe.cprint(self._phase_prefix() + msg)
def _li_recurse_progress_output(self, lin):
@@ -2206,8 +2228,10 @@
extra_info = ""
if isinstance(planitem, GoalTrackerItem):
extra_info = ": %s" % planitem.pair()
- msg = _("Creating Plan (%s%s): %s") % \
- (planitem.name, extra_info, self._spinner())
+ msg = _("Creating Plan (%(name)s%(info)s): %(spinner)s") % \
+ {"name": planitem.name,
+ "info": extra_info,
+ "spinner": self._spinner()}
self._pe.cprint(msg, sep='', end='', erase=True)
def _plan_output_all_done(self):
@@ -2228,12 +2252,19 @@
# the output based on the major mode.
#
if self.major_phase == self.PHASE_PLAN:
- msg = _("Creating Plan (%s %s) %c") % \
- (self.mfst_fetch.name, self.mfst_fetch.pair(),
- self._spinner())
+ msg = _("Creating Plan (%(name)s %(pair)s) "
+ "%(spinner)c") % \
+ {"name": self.mfst_fetch.name,
+ "pair": self.mfst_fetch.pair(),
+ "spinner": self._spinner()}
if self.major_phase == self.PHASE_UTILITY:
- msg = _("%s (%s) %c") % (self.mfst_fetch.name,
- self.mfst_fetch.pair(), self._spinner())
+ # note to translators: the position of these strings
+ # should probably be left alone, as they form part of
+ # the progress output text.
+ msg = _("%(name)s (%(fetchpair)s) %(spinchar)c") % {
+ "name": self.mfst_fetch.name,
+ "fetchpair": self.mfst_fetch.pair(),
+ "spinchar": self._spinner()}
self._pe.cprint(msg, sep='', end='', erase=True)
if outspec.last:
@@ -2477,10 +2508,12 @@
assert self.major_phase in self.li_phase_names, self.major_phase
running = " ".join([str(i) for i in self.linked_running])
- msg = _("%s linked: %s done; %d working: %s") % \
- (self.li_phase_names[self.major_phase],
- format_pair("%d", done, self.linked_total),
- len(self.linked_running), running)
+ msg = _("%(phase)s linked: %(numdone)s done; "
+ "%(numworking)d working: %(running)s") % \
+ {"phase": self.li_phase_names[self.major_phase],
+ "numdone": format_pair("%d", done, self.linked_total),
+ "numworking": len(self.linked_running),
+ "running": running}
self._pe.cprint(msg, erase=True)
self.__linked_spinners = list(
--- a/src/modules/flavor/base.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/flavor/base.py Fri Nov 02 11:42:49 2012 +1300
@@ -53,9 +53,11 @@
if not self.dirs:
return _("Couldn't find '%s'") % self.file_path
else:
- return _("Couldn't find '%s' in any of the specified "
- "search directories:\n%s") % (self.file_path,
- "\n".join(["\t" + d for d in sorted(self.dirs)]))
+ return _("Couldn't find '%(path)s' in any of the "
+ "specified search directories:\n%(dirs)s") % \
+ {"path": self.file_path,
+ "dirs": "\n".join(
+ ["\t" + d for d in sorted(self.dirs)])}
class MultipleDefaultRunpaths(DependencyAnalysisError):
"""Exception that is raised when multiple $PGKDEPEND_RUNPATH tokens
--- a/src/modules/flavor/elf.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/flavor/elf.py Fri Nov 02 11:42:49 2012 +1300
@@ -42,7 +42,8 @@
self.ex = ex
def __str__(self):
- return _("%s had this elf error:%s") % (self.fp, self.ex)
+ return _("%(file)s had this elf error:%(err)s") % \
+ {"file": "self.fp", "err": self.ex}
class UnsupportedDynamicToken(base.DependencyAnalysisError):
"""Exception that is used for elf dependencies which have a dynamic
--- a/src/modules/gui/beadmin.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/gui/beadmin.py Fri Nov 02 11:42:49 2012 +1300
@@ -391,8 +391,10 @@
msg += _("<b>Couldn't rename Boot "
"Environments:</b>\n")
for orig in not_renamed:
- msg += _("%s <b>to</b> %s\n") % (orig, \
- not_renamed.get(orig))
+ msg += _("%(src)s <b>to</b> "
+ "%(targ)s\n") % \
+ {"src": orig,
+ "targ": not_renamed.get(orig)}
gobject.idle_add(self.__error_occurred, msg)
return
gobject.idle_add(self.__on_cancel_be_clicked, None)
--- a/src/modules/gui/misc.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/gui/misc.py Fri Nov 02 11:42:49 2012 +1300
@@ -396,8 +396,10 @@
try:
api_o = ngao(img_dir, progtrack)
except api_errors.VersionException, ex:
- message = _("Version mismatch: expected version %d, got version %d") % \
- (ex.expected_version, ex.received_version)
+ message = _("Version mismatch: expected version %(expected)d, "
+ "got version %(found)d") % \
+ {"expected": ex.expected_version,
+ "found": ex.received_version}
except api_errors.ImageNotFoundException, ex:
message = _("%s is not an install image") % ex.user_dir
except api_errors.ImageLockedError, ex:
--- a/src/modules/gui/progress.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/gui/progress.py Fri Nov 02 11:42:49 2012 +1300
@@ -142,9 +142,10 @@
self.display_download_info()
if "startpkg" in outspec.changed:
self.update_details_text(
- _("Package %d of %d: %s\n") % (
- self.dl_pkgs.items + 1,
- self.dl_pkgs.goalitems, self.dl_pkgs.curinfo),
+ _("Package %(num)d of %(goal)d: %(info)s\n") % {
+ "num": self.dl_pkgs.items + 1,
+ "goal": self.dl_pkgs.goalitems,
+ "info": self.dl_pkgs.curinfo},
"level1")
if outspec.last:
@@ -223,9 +224,11 @@
i = "level1" if self.indent else ""
running = " ".join([str(s) for s in self.linked_running])
- msg = _("Linked images: %s done; %d working: %s\n") % \
- (progress.format_pair("%d", done, self.linked_total),
- len(self.linked_running), running)
+ msg = _("Linked images: %(num)s done; %(numworking)d working: "
+ "%(running)s\n") % \
+ {"num": progress.format_pair("%d", done, self.linked_total),
+ "numworking": len(self.linked_running),
+ "running": running}
self.update_details_text(msg, i)
def _li_recurse_progress_output(self, lin):
--- a/src/modules/gui/uarenamebe.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/gui/uarenamebe.py Fri Nov 02 11:42:49 2012 +1300
@@ -220,8 +220,9 @@
def __g_be_rename_problem_dialog(new_name, orig_name):
msg_type = gtk.MESSAGE_INFO
error_msg = _("Could not change the BE name to:\n\t"
- "%s\n\nThe following name will be used instead:"
- "\n\t%s" % (new_name, orig_name))
+ "%(targ)s\n\nThe following name will be used instead:"
+ "\n\t%(instead)s") % \
+ {"targ": new_name, "instead": orig_name}
msg_title = _("BE Name")
gui_misc.error_occurred(None, error_msg, msg_title, msg_type)
--- a/src/modules/misc.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/misc.py Fri Nov 02 11:42:49 2012 +1300
@@ -1352,8 +1352,9 @@
if opt == opts_seen[k]:
usage_cb(_("option '%s' repeated") % opt,
cmd=op)
- usage_cb(_("'%s' and '%s' have the same meaning") %
- (opts_seen[k], opt), cmd=op)
+ usage_cb(_("'%(optA)s' and '%(optB)s' have the same "
+ "meaning") % {"optA": opts_seen[k], "optB": opt},
+ cmd=op)
opts_seen[k] = opt
# update the return dict value
--- a/src/modules/server/transaction.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/modules/server/transaction.py Fri Nov 02 11:42:49 2012 +1300
@@ -551,14 +551,16 @@
raise TransactionOperationError(_("A package may not "
" be marked for both obsoletion and renaming."))
elif self.obsolete and action.name not in ("set", "signature"):
- raise TransactionOperationError(_("A '%s' action cannot"
- " be present in an obsolete package: %s") %
- (action.name, action))
+ raise TransactionOperationError(_("A '%(type)s' action "
+ "cannot be present in an obsolete package: "
+ "%(action)s") %
+ {"type": action.name, "action": action})
elif self.renamed and action.name not in \
("depend", "set", "signature"):
- raise TransactionOperationError(_("A '%s' action cannot"
- " be present in a renamed package: %s") %
- (action.name, action))
+ raise TransactionOperationError(_("A '%(type)s' action "
+ "cannot be present in a renamed package: "
+ "%(action)s") %
+ {"type": action.name, "action": action})
# Now that the action is known to be sane, we can add it to the
# manifest.
--- a/src/pkg/external_deps.txt Wed Oct 31 10:48:34 2012 -0700
+++ b/src/pkg/external_deps.txt Fri Nov 02 11:42:49 2012 +1300
@@ -42,6 +42,7 @@
pkg:/system/linker
pkg:/system/locale/extra
pkg:/system/network
+ pkg:/text/gnu-gettext
pkg:/text/gnu-grep
pkg:/text/locale
pkg:/text/tidy
--- a/src/pkg/manifests/developer:opensolaris:pkg5.p5m Wed Oct 31 10:48:34 2012 -0700
+++ b/src/pkg/manifests/developer:opensolaris:pkg5.p5m Fri Nov 02 11:42:49 2012 +1300
@@ -49,6 +49,7 @@
depend type=require fmri=pkg:/system/header
depend type=require fmri=pkg:/system/linker
depend type=require fmri=pkg:/system/locale/extra
+depend type=require fmri=pkg:/text/gnu-gettext
depend type=require fmri=pkg:/text/locale
depend type=require fmri=pkg:/text/tidy
depend type=require fmri=pkg:/web/server/apache-22
--- a/src/pkg/manifests/package:pkg.p5m Wed Oct 31 10:48:34 2012 -0700
+++ b/src/pkg/manifests/package:pkg.p5m Fri Nov 02 11:42:49 2012 +1300
@@ -297,6 +297,70 @@
file path=usr/share/lib/pkg/web/index.shtml
file path=usr/share/lib/pkg/web/robots.txt
file path=usr/share/lib/pkg/web/shared.shtml
+dir path=usr/share/locale
+dir path=usr/share/locale/ar
+dir path=usr/share/locale/ar/LC_MESSAGES
+file path=usr/share/locale/ar/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/ca
+dir path=usr/share/locale/ca/LC_MESSAGES
+file path=usr/share/locale/ca/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/cs
+dir path=usr/share/locale/cs/LC_MESSAGES
+file path=usr/share/locale/cs/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/de
+dir path=usr/share/locale/de/LC_MESSAGES
+file path=usr/share/locale/de/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/es
+dir path=usr/share/locale/es/LC_MESSAGES
+file path=usr/share/locale/es/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/fr
+dir path=usr/share/locale/fr/LC_MESSAGES
+file path=usr/share/locale/fr/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/he
+dir path=usr/share/locale/he/LC_MESSAGES
+file path=usr/share/locale/he/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/hu
+dir path=usr/share/locale/hu/LC_MESSAGES
+file path=usr/share/locale/hu/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/id
+dir path=usr/share/locale/id/LC_MESSAGES
+file path=usr/share/locale/id/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/it
+dir path=usr/share/locale/it/LC_MESSAGES
+file path=usr/share/locale/it/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/ja
+dir path=usr/share/locale/ja/LC_MESSAGES
+file path=usr/share/locale/ja/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/ko
+dir path=usr/share/locale/ko/LC_MESSAGES
+file path=usr/share/locale/ko/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/nl
+dir path=usr/share/locale/nl/LC_MESSAGES
+file path=usr/share/locale/nl/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/pl
+dir path=usr/share/locale/pl/LC_MESSAGES
+file path=usr/share/locale/pl/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/pt_BR
+dir path=usr/share/locale/pt_BR/LC_MESSAGES
+file path=usr/share/locale/pt_BR/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/ru
+dir path=usr/share/locale/ru/LC_MESSAGES
+file path=usr/share/locale/ru/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/sk
+dir path=usr/share/locale/sk/LC_MESSAGES
+file path=usr/share/locale/sk/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/sv
+dir path=usr/share/locale/sv/LC_MESSAGES
+file path=usr/share/locale/sv/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/zh_CN
+dir path=usr/share/locale/zh_CN/LC_MESSAGES
+file path=usr/share/locale/zh_CN/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/zh_HK
+dir path=usr/share/locale/zh_HK/LC_MESSAGES
+file path=usr/share/locale/zh_HK/LC_MESSAGES/pkg.mo
+dir path=usr/share/locale/zh_TW
+dir path=usr/share/locale/zh_TW/LC_MESSAGES
+file path=usr/share/locale/zh_TW/LC_MESSAGES/pkg.mo
dir path=usr/share/man
dir path=usr/share/man/ja_JP.UTF-8
dir path=usr/share/man/ja_JP.UTF-8/man1
--- a/src/pkg/manifests/package:pkg:package-manager.p5m Wed Oct 31 10:48:34 2012 -0700
+++ b/src/pkg/manifests/package:pkg:package-manager.p5m Fri Nov 02 11:42:49 2012 +1300
@@ -18,7 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
#
set name=pkg.fmri value=pkg:/package/pkg/package-manager@$(PKGVERS)
@@ -132,70 +132,6 @@
file path=usr/share/icons/hicolor/48x48/apps/packagemanager.png
dir path=usr/share/icons/hicolor/48x48/mimetypes
file path=usr/share/icons/hicolor/48x48/mimetypes/gnome-mime-application-vnd.pkg5.info.png
-dir path=usr/share/locale
-dir path=usr/share/locale/ar
-dir path=usr/share/locale/ar/LC_MESSAGES
-file path=usr/share/locale/ar/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/ca
-dir path=usr/share/locale/ca/LC_MESSAGES
-file path=usr/share/locale/ca/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/cs
-dir path=usr/share/locale/cs/LC_MESSAGES
-file path=usr/share/locale/cs/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/de
-dir path=usr/share/locale/de/LC_MESSAGES
-file path=usr/share/locale/de/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/es
-dir path=usr/share/locale/es/LC_MESSAGES
-file path=usr/share/locale/es/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/fr
-dir path=usr/share/locale/fr/LC_MESSAGES
-file path=usr/share/locale/fr/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/he
-dir path=usr/share/locale/he/LC_MESSAGES
-file path=usr/share/locale/he/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/hu
-dir path=usr/share/locale/hu/LC_MESSAGES
-file path=usr/share/locale/hu/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/id
-dir path=usr/share/locale/id/LC_MESSAGES
-file path=usr/share/locale/id/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/it
-dir path=usr/share/locale/it/LC_MESSAGES
-file path=usr/share/locale/it/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/ja
-dir path=usr/share/locale/ja/LC_MESSAGES
-file path=usr/share/locale/ja/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/ko
-dir path=usr/share/locale/ko/LC_MESSAGES
-file path=usr/share/locale/ko/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/nl
-dir path=usr/share/locale/nl/LC_MESSAGES
-file path=usr/share/locale/nl/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/pl
-dir path=usr/share/locale/pl/LC_MESSAGES
-file path=usr/share/locale/pl/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/pt_BR
-dir path=usr/share/locale/pt_BR/LC_MESSAGES
-file path=usr/share/locale/pt_BR/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/ru
-dir path=usr/share/locale/ru/LC_MESSAGES
-file path=usr/share/locale/ru/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/sk
-dir path=usr/share/locale/sk/LC_MESSAGES
-file path=usr/share/locale/sk/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/sv
-dir path=usr/share/locale/sv/LC_MESSAGES
-file path=usr/share/locale/sv/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/zh_CN
-dir path=usr/share/locale/zh_CN/LC_MESSAGES
-file path=usr/share/locale/zh_CN/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/zh_HK
-dir path=usr/share/locale/zh_HK/LC_MESSAGES
-file path=usr/share/locale/zh_HK/LC_MESSAGES/pkg.mo
-dir path=usr/share/locale/zh_TW
-dir path=usr/share/locale/zh_TW/LC_MESSAGES
-file path=usr/share/locale/zh_TW/LC_MESSAGES/pkg.mo
dir path=usr/share/man
dir path=usr/share/man/ja_JP.UTF-8
dir path=usr/share/man/ja_JP.UTF-8/man1
--- a/src/pkgdep.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/pkgdep.py Fri Nov 02 11:42:49 2012 +1300
@@ -489,8 +489,13 @@
try:
os.makedirs(out_dir)
except EnvironmentError, e:
- emsg(_("Out dir %s does not exist and could not be "
- "created. Error is: %s") % e)
+ e_dic = {"dir": out_dir}
+ if len(e.args) > 0:
+ e_dic["err"] = e.args[1]
+ else:
+ e_dic["err"] = e.args[0]
+ emsg(_("Out dir %(out_dir)s does not exist and could "
+ "not be created. Error is: %(err)s") % e_dic)
return 1
if suffix and suffix[0] != ".":
suffix = "." + suffix
--- a/src/publish.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/publish.py Fri Nov 02 11:42:49 2012 +1300
@@ -359,7 +359,8 @@
filename = "???"
lineno = "???"
- error(_("File %s line %s: %s") % (filename, lineno, e),
+ error(_("File %(filename)s line %(lineno)s: %(err)s") %
+ {"filename": filename, "lineno": lineno, "err": e},
cmd="publish")
return 1
@@ -508,7 +509,8 @@
filename = "???"
lineno = "???"
- error(_("File %s line %s: %s") % (filename, lineno, e),
+ error(_("File %(filename)s line %(lineno)s: %(err)s") %
+ {"filename": filename, "lineno": lineno, "err": e},
cmd="include")
return 1
@@ -790,7 +792,8 @@
error(e, cmd=subcommand)
ret = 1
except getopt.GetoptError, e:
- usage(_("illegal %s option -- %s") % (subcommand, e.opt))
+ usage(_("illegal %(cmd)s option -- %(opt)s") % \
+ {"cmd": subcommand, "opt": e.opt})
return ret
--- a/src/pull.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/pull.py Fri Nov 02 11:42:49 2012 +1300
@@ -747,7 +747,8 @@
os.makedirs(basedir, misc.PKG_DIR_MODE)
except Exception, e:
error(_("Unable to create basedir "
- "'%s': %s") % (basedir, e))
+ "'%(dir)s': %(err)s") %
+ {"dir": basedir, "err": e})
abort()
xport_cfg.pkg_root = basedir
--- a/src/setup.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/setup.py Fri Nov 02 11:42:49 2012 +1300
@@ -37,6 +37,7 @@
import py_compile
import hashlib
import time
+import StringIO
from distutils.errors import DistutilsError, DistutilsFileError
from distutils.core import setup
@@ -730,7 +731,7 @@
rm_f(dst)
os.symlink(src, dst)
-def run_cmd(args, swdir, updenv=None, ignerr=False):
+def run_cmd(args, swdir, updenv=None, ignerr=False, savestderr=None):
if updenv:
# use temp environment modified with the given dict
env = os.environ.copy()
@@ -741,6 +742,8 @@
if ignerr:
# send stderr to devnull
stderr = open(os.devnull)
+ elif savestderr:
+ stderr = savestderr
else:
# just use stderr of this (parent) process
stderr = None
@@ -877,6 +880,50 @@
print " ".join(args)
run_cmd(args, os.getcwd(), updenv={"LC_ALL": "C"})
+def i18n_check():
+ """Checks for common i18n messaging bugs in the source."""
+
+ src_files = []
+ # A list of the i18n errors we check for in the code
+ common_i18n_errors = [
+ # This checks that messages with multiple parameters are always
+ # written using "%(name)s" format, rather than just "%s"
+ "format string with unnamed arguments cannot be properly localized"
+ ]
+
+ for line in open("po/POTFILES.in", "r").readlines():
+ if line.startswith("["):
+ continue
+ if line.startswith("#"):
+ continue
+ src_files.append(line.rstrip())
+
+ args = [
+ "/usr/gnu/bin/xgettext", "--from-code=UTF-8", "-o", "/dev/null"]
+ args += src_files
+
+ xgettext_output_path = tempfile.mkstemp()[1]
+ xgettext_output = open(xgettext_output_path, "w")
+ run_cmd(args, os.getcwd(), updenv={"LC_ALL": "C"},
+ savestderr=xgettext_output)
+
+ found_errs = False
+ i18n_errs = open("po/i18n_errs.txt", "w")
+ for line in open(xgettext_output_path, "r").readlines():
+ for err in common_i18n_errors:
+ if err in line:
+ i18n_errs.write(line)
+ found_errs = True
+ i18n_errs.close()
+ if found_errs:
+ print >> sys.stderr, \
+"The following i18n errors were detected and should be corrected:\n" \
+"(this list is saved in po/i18n_errs.txt)\n"
+ for line in open("po/i18n_errs.txt", "r"):
+ print >> sys.stderr, line.rstrip()
+ sys.exit(1)
+ os.remove(xgettext_output_path)
+
def msgfmt(src, dst):
if not dep_util.newer(src, dst):
return
@@ -1227,6 +1274,7 @@
def run(self):
# Anything that gets created here should get deleted in
# clean_func.run() below.
+ i18n_check()
for f in intl_files:
intltool_merge(f, f[:-3])
@@ -1292,6 +1340,7 @@
rm_f("gui/help/C/pkg_help.pot")
rm_f("gui/help/package-manager-__LOCALE__.omf")
+ rm_f("po/i18n_errs.txt")
class clobber_func(Command):
user_options = []
--- a/src/tests/cli/t_pkg_image_create.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/tests/cli/t_pkg_image_create.py Fri Nov 02 11:42:49 2012 +1300
@@ -257,7 +257,7 @@
saved_sysrepo_env = os.environ.get("PKG_SYSREPO_URL")
os.environ["PKG_SYSREPO_URL"] = "http://localhost:1"
self.pkg("image-create --no-refresh --set-property \
- use-system-repo=true %s" %(img_path))
+ use-system-repo=true %s" % img_path)
shutil.rmtree(img_path)
if saved_sysrepo_env:
os.environ["PKG_SYSREPO_URL"] = saved_sysrepo_env
--- a/src/util/publish/pkgdiff.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/util/publish/pkgdiff.py Fri Nov 02 11:42:49 2012 +1300
@@ -144,7 +144,8 @@
# of the same name have the same values defined.
for k in set(v1.keys()) & set(v2.keys()):
if v1[k] != v2[k]:
- error(_("Manifests support different variants %s %s") % (v1, v2))
+ error(_("Manifests support different variants "
+ "%(v1)s %(v2)s") % {"v1": v1, "v2": v2})
# Now, get a list of all possible variant values, including None
# across all variants and both manifests
--- a/src/util/publish/pkglint.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/util/publish/pkglint.py Fri Nov 02 11:42:49 2012 +1300
@@ -239,13 +239,15 @@
f = codecs.open(filename, "rb", "utf-8")
data = f.read()
except UnicodeDecodeError, e:
- lint_logger.critical(_("Invalid file %s: "
- "manifest not encoded in UTF-8: %s") %
- (filename, e), msgid="lint.manifest002")
+ lint_logger.critical(_("Invalid file %(file)s: "
+ "manifest not encoded in UTF-8: %(err)s") %
+ {"file": filename, "err": e},
+ msgid="lint.manifest002")
continue
except IOError, e:
lint_logger.critical(_("Unable to read manifest file "
- "%s: %s") % (filename, e), msgid="lint.manifest001")
+ "%(file)s: %(err)s") % {"file": filename, "err": e},
+ msgid="lint.manifest001")
continue
lines.append(data)
linecnt = len(data.splitlines())
--- a/src/util/publish/pkgmogrify.py Wed Oct 31 10:48:34 2012 -0700
+++ b/src/util/publish/pkgmogrify.py Fri Nov 02 11:42:49 2012 +1300
@@ -79,8 +79,9 @@
attrdict[a] = re.compile(attrdict[a])
except re.error, e:
raise RuntimeError, \
- _("transform (%s) has regexp error (%s) in matching clause"
- ) % (transform, e)
+ _("transform (%(transform)s) has regexp error "
+ "(%(err)s) in matching clause"
+ ) % {"transform": transform, "err": e}
op = s[index+2:].strip().split(None, 1)
@@ -215,8 +216,9 @@
regexp = args[1]
except re.error, e:
raise RuntimeError, \
- _("transform (%s) has 'edit' operation with malformed "
- "regexp (%s)") % (transform, e)
+ _("transform (%(transform)s) has 'edit' operation "
+ "with malformed regexp (%(err)s)") % \
+ {"transform": transform, "err": e}
if len(args) == 3:
replace = args[2]
@@ -249,8 +251,10 @@
]
except re.error, e:
raise RuntimeError, \
- _("transform (%s) has edit operation with replacement"
- "string regexp error %e") % (transform, e)
+ _("transform (%(transform)s) has edit "
+ "operation with replacement string regexp "
+ "error %(err)e") % \
+ {"transform": transform, "err": e}
return action
operation = replace_func
@@ -272,8 +276,9 @@
regexp = re.compile(args[1])
except re.error, e:
raise RuntimeError, \
- _("transform (%s) has 'delete' operation with malformed "
- "regexp (%s)") % (transform, e)
+ _("transform (%(transform)s) has 'delete' operation"
+ "with malformed regexp (%(err)s)") % \
+ {"transform": transform, "err": e}
def delete_func(action, matches, pkg_attrs, filename, lineno):
val = attrval_as_list(action.attrs, attr)
@@ -292,8 +297,10 @@
del action.attrs[attr]
except re.error, e:
raise RuntimeError, \
- _("transform (%s) has delete operation with replacement"
- "string regexp error %e") % (transform, e)
+ _("transform (%(transform)s) has delete "
+ "operation with replacement string regexp "
+ "error %(err)e") % \
+ {"transform": transform, "err": e}
return action
operation = delete_func
@@ -454,8 +461,9 @@
ref = int(i.string[slice(*i.span())][2:-1])
if ref == 0 or ref > len(backrefs) - 1:
- raise RuntimeError, _("no match group %d (max %d)") % \
- (ref, len(backrefs) - 1)
+ raise RuntimeError, _("no match group %(group)d "
+ "(max %(maxgroups)d)") % \
+ {"group": ref, "maxgroups": len(backrefs) - 1}
newmsg += msg[prevend:i.start()] + backrefs[ref]
prevend = i.end()