mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Extract voxygen/src/i18n.rs into own crate
- New crate (i18n), currently under voxygen directory - Updated CI to run localization test from i18n, not from voxygen
This commit is contained in:
parent
50e992ed0d
commit
5573fc33b9
@ -6,7 +6,7 @@ unittests:
|
|||||||
script:
|
script:
|
||||||
- ln -s /dockercache/cache-all target
|
- ln -s /dockercache/cache-all target
|
||||||
- rm -r target/debug/incremental/veloren_* || echo "all good" # TMP FIX FOR 2021-03-22-nightly
|
- rm -r target/debug/incremental/veloren_* || echo "all good" # TMP FIX FOR 2021-03-22-nightly
|
||||||
- cargo test --package veloren-voxygen --lib test_all_localizations -- --nocapture --ignored
|
- cargo test --package veloren-i18n --lib test_all_localizations -- --nocapture --ignored
|
||||||
- rm -r target/debug/incremental* || echo "all good" # TMP FIX FOR 2021-03-22-nightly
|
- rm -r target/debug/incremental* || echo "all good" # TMP FIX FOR 2021-03-22-nightly
|
||||||
- cargo test
|
- cargo test
|
||||||
retry:
|
retry:
|
||||||
|
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -5644,11 +5644,14 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "veloren-i18n-check"
|
name = "veloren-i18n"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"assets_manager",
|
||||||
|
"deunicode",
|
||||||
"git2",
|
"git2",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
|
"lazy_static",
|
||||||
"ron",
|
"ron",
|
||||||
"serde",
|
"serde",
|
||||||
"tracing",
|
"tracing",
|
||||||
@ -5854,7 +5857,7 @@ dependencies = [
|
|||||||
"veloren-common-net",
|
"veloren-common-net",
|
||||||
"veloren-common-state",
|
"veloren-common-state",
|
||||||
"veloren-common-systems",
|
"veloren-common-systems",
|
||||||
"veloren-i18n-check",
|
"veloren-i18n",
|
||||||
"veloren-server",
|
"veloren-server",
|
||||||
"veloren-voxygen-anim",
|
"veloren-voxygen-anim",
|
||||||
"veloren-world",
|
"veloren-world",
|
||||||
|
@ -18,7 +18,7 @@ members = [
|
|||||||
"voxygen",
|
"voxygen",
|
||||||
"voxygen/anim",
|
"voxygen/anim",
|
||||||
"voxygen/anim/dyn",
|
"voxygen/anim/dyn",
|
||||||
"voxygen/i18n-check",
|
"voxygen/i18n",
|
||||||
"world",
|
"world",
|
||||||
"network",
|
"network",
|
||||||
"network/protocol",
|
"network/protocol",
|
||||||
|
@ -42,7 +42,7 @@ common-systems = {package = "veloren-common-systems", path = "../common/systems"
|
|||||||
common-state = {package = "veloren-common-state", path = "../common/state"}
|
common-state = {package = "veloren-common-state", path = "../common/state"}
|
||||||
|
|
||||||
anim = {package = "veloren-voxygen-anim", path = "anim"}
|
anim = {package = "veloren-voxygen-anim", path = "anim"}
|
||||||
i18n-check = {package = "veloren-i18n-check", path = "i18n-check"}
|
i18n = {package = "veloren-i18n", path = "i18n"}
|
||||||
|
|
||||||
# Graphics
|
# Graphics
|
||||||
gfx = "0.18.2"
|
gfx = "0.18.2"
|
||||||
|
@ -1 +0,0 @@
|
|||||||
pub mod analysis;
|
|
@ -1,16 +1,20 @@
|
|||||||
[package]
|
[package]
|
||||||
authors = ["juliancoffee <lightdarkdaughter@gmail.com>"]
|
authors = ["juliancoffee <lightdarkdaughter@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "veloren-i18n-check"
|
name = "veloren-i18n"
|
||||||
description = "crate to analyze localization assets to find what needs update"
|
description = "Crate for internalization and diagnostic of existing localizations."
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "i18n-check"
|
name = "i18n-check"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
hashbrown = { version = "0.9", features = ["rayon", "serde", "nightly"] }
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
assets_manager = {version = "0.4.2", features = ["bincode", "ron", "json", "hot-reloading"]}
|
||||||
|
deunicode = "1.0"
|
||||||
|
ron = "0.6"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
ron = "0.6"
|
# Diagnostic
|
||||||
git2 = "0.13"
|
git2 = "0.13"
|
||||||
hashbrown = { version = "0.9", features = ["rayon", "serde", "nightly"] }
|
|
151
voxygen/i18n/src/assets.rs
Normal file
151
voxygen/i18n/src/assets.rs
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
//! Load assets (images or voxel data) from files
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
pub use assets_manager::{
|
||||||
|
asset::Ron,
|
||||||
|
loader::{
|
||||||
|
self, BincodeLoader, BytesLoader, JsonLoader, LoadFrom, Loader, RonLoader, StringLoader,
|
||||||
|
},
|
||||||
|
source, Asset, AssetCache, BoxedError, Compound, Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
/// The HashMap where all loaded assets are stored in.
|
||||||
|
static ref ASSETS: AssetCache = AssetCache::new(&*ASSETS_PATH).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type AssetHandle<T> = assets_manager::Handle<'static, T>;
|
||||||
|
pub type AssetGuard<T> = assets_manager::AssetGuard<'static, T>;
|
||||||
|
|
||||||
|
/// The Asset trait, which is implemented by all structures that have their data
|
||||||
|
/// stored in the filesystem.
|
||||||
|
pub trait AssetExt: Sized + Send + Sync + 'static {
|
||||||
|
/// Function used to load assets from the filesystem or the cache.
|
||||||
|
fn load(specifier: &str) -> Result<AssetHandle<Self>, Error>;
|
||||||
|
|
||||||
|
/// Function used to load assets from the filesystem or the cache and return
|
||||||
|
/// a clone.
|
||||||
|
fn load_cloned(specifier: &str) -> Result<Self, Error>
|
||||||
|
where
|
||||||
|
Self: Clone,
|
||||||
|
{
|
||||||
|
Self::load(specifier).map(AssetHandle::cloned)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Function used to load essential assets from the filesystem or the cache.
|
||||||
|
/// It will panic if the asset is not found.
|
||||||
|
#[track_caller]
|
||||||
|
fn load_expect(specifier: &str) -> AssetHandle<Self> {
|
||||||
|
Self::load(specifier).unwrap_or_else(|err| {
|
||||||
|
panic!(
|
||||||
|
"Failed loading essential asset: {} (error={:?})",
|
||||||
|
specifier, err
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Function used to load essential assets from the filesystem or the cache
|
||||||
|
/// and return a clone. It will panic if the asset is not found.
|
||||||
|
#[track_caller]
|
||||||
|
fn load_expect_cloned(specifier: &str) -> Self
|
||||||
|
where
|
||||||
|
Self: Clone,
|
||||||
|
{
|
||||||
|
Self::load_expect(specifier).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_owned(specifier: &str) -> Result<Self, Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Compound> AssetExt for T {
|
||||||
|
fn load(specifier: &str) -> Result<AssetHandle<Self>, Error> { ASSETS.load(specifier) }
|
||||||
|
|
||||||
|
fn load_owned(specifier: &str) -> Result<Self, Error> { ASSETS.load_owned(specifier) }
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
/// Lazy static to find and cache where the asset directory is.
|
||||||
|
/// Cases we need to account for:
|
||||||
|
/// 1. Running through airshipper (`assets` next to binary)
|
||||||
|
/// 2. Install with package manager and run (assets probably in `/usr/share/veloren/assets` while binary in `/usr/bin/`)
|
||||||
|
/// 3. Download & hopefully extract zip (`assets` next to binary)
|
||||||
|
/// 4. Running through cargo (`assets` in workspace root but not always in cwd incase you `cd voxygen && cargo r`)
|
||||||
|
/// 5. Running executable in the target dir (`assets` in workspace)
|
||||||
|
pub static ref ASSETS_PATH: PathBuf = {
|
||||||
|
let mut paths = Vec::new();
|
||||||
|
|
||||||
|
// Note: Ordering matters here!
|
||||||
|
|
||||||
|
// 1. VELOREN_ASSETS environment variable
|
||||||
|
if let Ok(var) = std::env::var("VELOREN_ASSETS") {
|
||||||
|
paths.push(var.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Executable path
|
||||||
|
if let Ok(mut path) = std::env::current_exe() {
|
||||||
|
path.pop();
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Working path
|
||||||
|
if let Ok(path) = std::env::current_dir() {
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Cargo Workspace (e.g. local development)
|
||||||
|
// https://github.com/rust-lang/cargo/issues/3946#issuecomment-359619839
|
||||||
|
if let Ok(Ok(path)) = std::env::var("CARGO_MANIFEST_DIR").map(|s| s.parse::<PathBuf>()) {
|
||||||
|
paths.push(path.parent().unwrap().to_path_buf());
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. System paths
|
||||||
|
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
|
||||||
|
{
|
||||||
|
if let Ok(result) = std::env::var("XDG_DATA_HOME") {
|
||||||
|
paths.push(format!("{}/veloren/", result).into());
|
||||||
|
} else if let Ok(result) = std::env::var("HOME") {
|
||||||
|
paths.push(format!("{}/.local/share/veloren/", result).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(result) = std::env::var("XDG_DATA_DIRS") {
|
||||||
|
result.split(':').for_each(|x| paths.push(format!("{}/veloren/", x).into()));
|
||||||
|
} else {
|
||||||
|
// Fallback
|
||||||
|
let fallback_paths = vec!["/usr/local/share", "/usr/share"];
|
||||||
|
for fallback_path in fallback_paths {
|
||||||
|
paths.push(format!("{}/veloren/", fallback_path).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::trace!("Possible asset locations paths={:?}", paths);
|
||||||
|
|
||||||
|
for mut path in paths.clone() {
|
||||||
|
if !path.ends_with("assets") {
|
||||||
|
path = path.join("assets");
|
||||||
|
}
|
||||||
|
|
||||||
|
if path.is_dir() {
|
||||||
|
tracing::info!("Assets found path={}", path.display());
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!(
|
||||||
|
"Asset directory not found. In attempting to find it, we searched:\n{})",
|
||||||
|
paths.iter().fold(String::new(), |mut a, path| {
|
||||||
|
a += &path.to_string_lossy();
|
||||||
|
a += "\n";
|
||||||
|
a
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the actual path of the specifier with the extension.
|
||||||
|
///
|
||||||
|
/// For directories, give `""` as extension.
|
||||||
|
pub fn path_of(specifier: &str, ext: &str) -> PathBuf { ASSETS.source().path_of(specifier, ext) }
|
@ -1,5 +1,5 @@
|
|||||||
use std::{env::args, path::Path, vec::Vec};
|
use std::{env::args, path::Path, vec::Vec};
|
||||||
use veloren_i18n_check::analysis;
|
use veloren_i18n::analysis;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cli: Vec<String> = args().collect();
|
let cli: Vec<String> = args().collect();
|
@ -1,4 +1,4 @@
|
|||||||
use common::assets::{self, AssetExt, AssetGuard, AssetHandle};
|
use crate::assets::{self, AssetExt, AssetGuard, AssetHandle};
|
||||||
use deunicode::deunicode;
|
use deunicode::deunicode;
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -332,7 +332,7 @@ impl LocalizationHandle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(specifier: &str) -> Result<Self, common::assets::Error> {
|
pub fn load(specifier: &str) -> Result<Self, crate::assets::Error> {
|
||||||
let default_key = i18n_asset_key(REFERENCE_LANG);
|
let default_key = i18n_asset_key(REFERENCE_LANG);
|
||||||
let is_default = specifier == default_key;
|
let is_default = specifier == default_key;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -390,7 +390,7 @@ pub fn i18n_asset_key(language_id: &str) -> String { ["voxygen.i18n.", language_
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use i18n_check::analysis;
|
use crate::analysis;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
// Test to verify all languages that they are VALID and loadable, without
|
// Test to verify all languages that they are VALID and loadable, without
|
||||||
@ -400,8 +400,8 @@ mod tests {
|
|||||||
// Generate paths
|
// Generate paths
|
||||||
let i18n_asset_path = Path::new("assets/voxygen/i18n/");
|
let i18n_asset_path = Path::new("assets/voxygen/i18n/");
|
||||||
let curr_dir = std::env::current_dir().unwrap();
|
let curr_dir = std::env::current_dir().unwrap();
|
||||||
let root = curr_dir.parent().unwrap();
|
let root_dir = curr_dir.parent().unwrap().parent().unwrap();
|
||||||
analysis::verify_all_localizations(&root, &i18n_asset_path);
|
analysis::verify_all_localizations(&root_dir, &i18n_asset_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test to verify all languages and print missing and faulty localisation
|
// Test to verify all languages and print missing and faulty localisation
|
||||||
@ -411,7 +411,7 @@ mod tests {
|
|||||||
// Generate paths
|
// Generate paths
|
||||||
let i18n_asset_path = Path::new("assets/voxygen/i18n/");
|
let i18n_asset_path = Path::new("assets/voxygen/i18n/");
|
||||||
let curr_dir = std::env::current_dir().unwrap();
|
let curr_dir = std::env::current_dir().unwrap();
|
||||||
let root = curr_dir.parent().unwrap();
|
let root_dir = curr_dir.parent().unwrap().parent().unwrap();
|
||||||
analysis::test_all_localizations(&root, &i18n_asset_path);
|
analysis::test_all_localizations(&root_dir, &i18n_asset_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
5
voxygen/i18n/src/lib.rs
Normal file
5
voxygen/i18n/src/lib.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
pub mod analysis;
|
||||||
|
mod assets;
|
||||||
|
mod i18n;
|
||||||
|
|
||||||
|
pub use i18n::*;
|
@ -19,7 +19,6 @@ pub mod controller;
|
|||||||
mod ecs;
|
mod ecs;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod hud;
|
pub mod hud;
|
||||||
pub mod i18n;
|
|
||||||
pub mod key_state;
|
pub mod key_state;
|
||||||
pub mod menu;
|
pub mod menu;
|
||||||
pub mod mesh;
|
pub mod mesh;
|
||||||
@ -35,12 +34,12 @@ pub mod window;
|
|||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use crate::error::Error;
|
pub use crate::error::Error;
|
||||||
|
pub use i18n;
|
||||||
|
|
||||||
#[cfg(feature = "singleplayer")]
|
#[cfg(feature = "singleplayer")]
|
||||||
use crate::singleplayer::Singleplayer;
|
use crate::singleplayer::Singleplayer;
|
||||||
use crate::{
|
use crate::{
|
||||||
audio::AudioFrontend,
|
audio::AudioFrontend,
|
||||||
i18n::LocalizationHandle,
|
|
||||||
profile::Profile,
|
profile::Profile,
|
||||||
render::Renderer,
|
render::Renderer,
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
@ -48,6 +47,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use common::clock::Clock;
|
use common::clock::Clock;
|
||||||
use common_base::span;
|
use common_base::span;
|
||||||
|
use i18n::LocalizationHandle;
|
||||||
|
|
||||||
/// A type used to store state that is shared between all play states.
|
/// A type used to store state that is shared between all play states.
|
||||||
pub struct GlobalState {
|
pub struct GlobalState {
|
||||||
|
Loading…
Reference in New Issue
Block a user