sess: try sysroot candidates for fluent bundle
Instead of checking only the user provided sysroot or the default (when no sysroot is provided), search user provided sysroot and then check default sysroots for locale requested by the user. Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
parent
4e1927db3c
commit
fc3cca24f1
5 changed files with 93 additions and 41 deletions
|
@ -11,7 +11,7 @@ use std::error::Error;
|
|||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
|
@ -45,7 +45,7 @@ pub enum TranslationBundleError {
|
|||
/// Failed to add `FluentResource` to `FluentBundle`.
|
||||
AddResource(FluentError),
|
||||
/// `$sysroot/share/locale/$locale` does not exist.
|
||||
MissingLocale(io::Error),
|
||||
MissingLocale,
|
||||
/// Cannot read directory entries of `$sysroot/share/locale/$locale`.
|
||||
ReadLocalesDir(io::Error),
|
||||
/// Cannot read directory entry of `$sysroot/share/locale/$locale`.
|
||||
|
@ -62,9 +62,7 @@ impl fmt::Display for TranslationBundleError {
|
|||
write!(f, "could not parse ftl file: {}", e)
|
||||
}
|
||||
TranslationBundleError::AddResource(e) => write!(f, "failed to add resource: {}", e),
|
||||
TranslationBundleError::MissingLocale(e) => {
|
||||
write!(f, "missing locale directory: {}", e)
|
||||
}
|
||||
TranslationBundleError::MissingLocale => write!(f, "missing locale directory"),
|
||||
TranslationBundleError::ReadLocalesDir(e) => {
|
||||
write!(f, "could not read locales dir: {}", e)
|
||||
}
|
||||
|
@ -84,7 +82,7 @@ impl Error for TranslationBundleError {
|
|||
TranslationBundleError::ReadFtl(e) => Some(e),
|
||||
TranslationBundleError::ParseFtl(e) => Some(e),
|
||||
TranslationBundleError::AddResource(e) => Some(e),
|
||||
TranslationBundleError::MissingLocale(e) => Some(e),
|
||||
TranslationBundleError::MissingLocale => None,
|
||||
TranslationBundleError::ReadLocalesDir(e) => Some(e),
|
||||
TranslationBundleError::ReadLocalesDirEntry(e) => Some(e),
|
||||
TranslationBundleError::LocaleIsNotDir => None,
|
||||
|
@ -113,7 +111,8 @@ impl From<Vec<FluentError>> for TranslationBundleError {
|
|||
/// (overriding any conflicting messages).
|
||||
#[instrument(level = "trace")]
|
||||
pub fn fluent_bundle(
|
||||
sysroot: &Path,
|
||||
mut user_provided_sysroot: Option<PathBuf>,
|
||||
mut sysroot_candidates: Vec<PathBuf>,
|
||||
requested_locale: Option<LanguageIdentifier>,
|
||||
additional_ftl_path: Option<&Path>,
|
||||
with_directionality_markers: bool,
|
||||
|
@ -140,33 +139,43 @@ pub fn fluent_bundle(
|
|||
|
||||
// If the user requests the default locale then don't try to load anything.
|
||||
if !requested_fallback_locale && let Some(requested_locale) = requested_locale {
|
||||
let mut sysroot = sysroot.to_path_buf();
|
||||
sysroot.push("share");
|
||||
sysroot.push("locale");
|
||||
sysroot.push(requested_locale.to_string());
|
||||
trace!(?sysroot);
|
||||
let mut found_resources = false;
|
||||
for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) {
|
||||
sysroot.push("share");
|
||||
sysroot.push("locale");
|
||||
sysroot.push(requested_locale.to_string());
|
||||
trace!(?sysroot);
|
||||
|
||||
let _ = sysroot.try_exists().map_err(TranslationBundleError::MissingLocale)?;
|
||||
|
||||
if !sysroot.is_dir() {
|
||||
return Err(TranslationBundleError::LocaleIsNotDir);
|
||||
}
|
||||
|
||||
for entry in sysroot.read_dir().map_err(TranslationBundleError::ReadLocalesDir)? {
|
||||
let entry = entry.map_err(TranslationBundleError::ReadLocalesDirEntry)?;
|
||||
let path = entry.path();
|
||||
trace!(?path);
|
||||
if path.extension().and_then(|s| s.to_str()) != Some("ftl") {
|
||||
if !sysroot.exists() {
|
||||
trace!("skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
let resource_str =
|
||||
fs::read_to_string(path).map_err(TranslationBundleError::ReadFtl)?;
|
||||
let resource =
|
||||
FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?;
|
||||
trace!(?resource);
|
||||
bundle.add_resource(resource).map_err(TranslationBundleError::from)?;
|
||||
if !sysroot.is_dir() {
|
||||
return Err(TranslationBundleError::LocaleIsNotDir);
|
||||
}
|
||||
|
||||
for entry in sysroot.read_dir().map_err(TranslationBundleError::ReadLocalesDir)? {
|
||||
let entry = entry.map_err(TranslationBundleError::ReadLocalesDirEntry)?;
|
||||
let path = entry.path();
|
||||
trace!(?path);
|
||||
if path.extension().and_then(|s| s.to_str()) != Some("ftl") {
|
||||
trace!("skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
let resource_str =
|
||||
fs::read_to_string(path).map_err(TranslationBundleError::ReadFtl)?;
|
||||
let resource =
|
||||
FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?;
|
||||
trace!(?resource);
|
||||
bundle.add_resource(resource).map_err(TranslationBundleError::from)?;
|
||||
found_resources = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !found_resources {
|
||||
return Err(TranslationBundleError::MissingLocale);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
|
|||
let sess = build_session(
|
||||
sessopts,
|
||||
None,
|
||||
None,
|
||||
registry,
|
||||
DiagnosticOutput::Default,
|
||||
Default::default(),
|
||||
|
|
|
@ -83,9 +83,23 @@ pub fn create_session(
|
|||
// target_override is documented to be called before init(), so this is okay
|
||||
let target_override = codegen_backend.target_override(&sopts);
|
||||
|
||||
let bundle = match rustc_errors::fluent_bundle(
|
||||
sopts.maybe_sysroot.clone(),
|
||||
sysroot_candidates(),
|
||||
sopts.debugging_opts.translate_lang.clone(),
|
||||
sopts.debugging_opts.translate_additional_ftl.as_deref(),
|
||||
sopts.debugging_opts.translate_directionality_markers,
|
||||
) {
|
||||
Ok(bundle) => bundle,
|
||||
Err(e) => {
|
||||
early_error(sopts.error_format, &format!("failed to load fluent bundle: {e}"));
|
||||
}
|
||||
};
|
||||
|
||||
let mut sess = session::build_session(
|
||||
sopts,
|
||||
input_path,
|
||||
bundle,
|
||||
descriptions,
|
||||
diagnostic_output,
|
||||
lint_caps,
|
||||
|
|
|
@ -20,8 +20,8 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
|
|||
use rustc_errors::json::JsonEmitter;
|
||||
use rustc_errors::registry::Registry;
|
||||
use rustc_errors::{
|
||||
fallback_fluent_bundle, fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
|
||||
EmissionGuarantee, ErrorGuaranteed, FluentBundle, MultiSpan,
|
||||
fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee,
|
||||
ErrorGuaranteed, FluentBundle, MultiSpan,
|
||||
};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
pub use rustc_span::def_id::StableCrateId;
|
||||
|
@ -1162,6 +1162,7 @@ pub enum DiagnosticOutput {
|
|||
pub fn build_session(
|
||||
sopts: config::Options,
|
||||
local_crate_source_file: Option<PathBuf>,
|
||||
bundle: Option<Lrc<rustc_errors::FluentBundle>>,
|
||||
registry: rustc_errors::registry::Registry,
|
||||
diagnostics_output: DiagnosticOutput,
|
||||
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
||||
|
@ -1214,16 +1215,17 @@ pub fn build_session(
|
|||
hash_kind,
|
||||
));
|
||||
|
||||
let bundle = fluent_bundle(
|
||||
&sysroot,
|
||||
sopts.debugging_opts.translate_lang.clone(),
|
||||
sopts.debugging_opts.translate_additional_ftl.as_deref(),
|
||||
sopts.debugging_opts.translate_directionality_markers,
|
||||
)
|
||||
.expect("failed to load fluent bundle");
|
||||
let fallback_bundle =
|
||||
fallback_fluent_bundle(sopts.debugging_opts.translate_directionality_markers)
|
||||
.expect("failed to load fallback fluent bundle");
|
||||
match fallback_fluent_bundle(sopts.debugging_opts.translate_directionality_markers) {
|
||||
Ok(bundle) => bundle,
|
||||
Err(e) => {
|
||||
early_error(
|
||||
sopts.error_format,
|
||||
&format!("failed to load fallback fluent bundle: {e}"),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let emitter =
|
||||
default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle, write_dest);
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@ normal: basic-translation.rs
|
|||
custom: basic-translation.rs basic-translation.ftl
|
||||
$(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/basic-translation.ftl 2>&1 | grep "this is a test message"
|
||||
|
||||
# Make a local copy of the sysroot and add the custom locale to it.
|
||||
# Check that a locale can be loaded from the sysroot given a language
|
||||
# identifier by making a local copy of the sysroot and adding the custom locale
|
||||
# to it.
|
||||
sysroot: basic-translation.rs basic-translation.ftl
|
||||
mkdir $(FAKEROOT)
|
||||
ln -s $(SYSROOT)/* $(FAKEROOT)
|
||||
|
@ -31,3 +33,27 @@ sysroot: basic-translation.rs basic-translation.ftl
|
|||
mkdir -p $(FAKEROOT)/share/locale/zh-CN/
|
||||
ln -s $(CURDIR)/basic-translation.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl
|
||||
$(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | grep "this is a test message"
|
||||
|
||||
# Check that the compiler errors out when the sysroot requested cannot be
|
||||
# found. This test might start failing if there actually exists a Klingon
|
||||
# translation of rustc's error messages.
|
||||
sysroot-missing:
|
||||
$(RUSTC) $< -Ztranslate-lang=tlh 2>&1 || grep "missing locale directory"
|
||||
|
||||
# Check that the compiler errors out when the sysroot requested cannot be
|
||||
# found. This test might start failing if there actually exists a Klingon
|
||||
# translation of rustc's error messages.
|
||||
sysroot-invalid: basic-translation.rs basic-translation.ftl
|
||||
mkdir $(FAKEROOT)
|
||||
ln -s $(SYSROOT)/* $(FAKEROOT)
|
||||
rm -f $(FAKEROOT)/lib
|
||||
mkdir $(FAKEROOT)/lib
|
||||
ln -s $(SYSROOT)/lib/* $(FAKEROOT)/lib
|
||||
rm -f $(FAKEROOT)/lib/rustlib
|
||||
mkdir $(FAKEROOT)/lib/rustlib
|
||||
ln -s $(SYSROOT)/lib/rustlib/* $(FAKEROOT)/lib/rustlib
|
||||
rm -f $(FAKEROOT)/lib/rustlib/src
|
||||
mkdir $(FAKEROOT)/lib/rustlib/src
|
||||
ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src
|
||||
touch $(FAKEROOT)/share/locale/zh-CN/
|
||||
$(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 || grep "`\$sysroot/share/locales/\$locale` is not a directory"
|
||||
|
|
Loading…
Reference in a new issue