Skip to content

Commit

Permalink
Rollup merge of #95716 - davidtwco:translation-custom-sysroot-only-wa…
Browse files Browse the repository at this point in the history
…rn, r=oli-obk

sess: warn w/out fluent bundle w/ user sysroot

Addresses #95512 (comment).

When a custom sysroot is requested, then don't error when translation resources are not found, only warn.

r? `@bjorn3`
  • Loading branch information
fee1-dead authored Apr 12, 2022
2 parents ae068e7 + fc3cca2 commit 305763e
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 42 deletions.
69 changes: 39 additions & 30 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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`.
Expand All @@ -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)
}
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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 _ = 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") {
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);

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);
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
let sess = build_session(
sessopts,
None,
None,
registry,
DiagnosticOutput::Default,
Default::default(),
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
24 changes: 13 additions & 11 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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);

Expand Down
28 changes: 27 additions & 1 deletion src/test/run-make/translation/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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"

0 comments on commit 305763e

Please sign in to comment.