Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Continuous Integration #20

Merged
merged 4 commits into from
May 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .github/workflows/compile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Compile

on:
pull_request:
branches: [ master ]

env:
CARGO_TERM_COLOR: always

jobs:
compile-windows:
name: Windows [Forked]
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: robinraju/release-downloader@v1.10
name: Download Forked Godot
with:
latest: true
fileName: 'FORKED_godot.windows.editor.x86_64.exe'
out-file-path: ./build
- name: Set executable env var
run: echo "GODOT4_BIN=$env:GITHUB_WORKSPACE/build/FORKED_godot.windows.editor.x86_64.exe" >> $env:GITHUB_ENV
- name: Build
working-directory: ./rust
run: cargo build --features forked-godot
- uses: actions/upload-artifact@v4
with:
name: FORKED_godot_fluent_translation_windows.dll
path: rust/target/debug/godot_fluent_translation.dll
compile-linux:
name: Linux [Default]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: robinraju/release-downloader@v1.10
name: Download Latest Godot
with:
repository: 'godotengine/godot-builds'
fileName: 'Godot_v4.3-dev6_linux.x86_64.zip'
tag: '4.3-dev6'
extract: true
out-file-path: ./build
- name: Make downloaded file executable
run: chmod +x ./build/Godot_v4.3-dev6_linux.x86_64
- name: Set executable env var
run: echo "GODOT4_BIN=$GITHUB_WORKSPACE/build/Godot_v4.3-dev6_linux.x86_64" >> $GITHUB_ENV
- name: Build
working-directory: ./rust
run: cargo build --features custom-godot
- uses: actions/upload-artifact@v4
with:
name: DEFAULT_godot_fluent_translation_linux.so
path: rust/target/debug/libgodot_fluent_translation.so
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"godotTools.editorPath.godot4": "./build/godot.windows.editor.x86_64.exe",
"rust-analyzer.cargo.features": ["forked-godot"],
"files.trimFinalNewlines": true,
"files.insertFinalNewline": true,
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ compatibility_minimum = 4.3
reloadable = true

[libraries]
linux.debug.x86_64 = "res://../rust/target/debug/libgodot-fluent-translation.so"
linux.release.x86_64 = "res://../rust/target/release/libgodot-fluent-translation.so"
windows.debug.x86_64 = "res://../rust/target/debug/godot-fluent-translation.dll"
windows.release.x86_64 = "res://../rust/target/release/godot-fluent-translation.dll"
macos.debug = "res://../rust/target/debug/libgodot-fluent-translation.dylib"
macos.release = "res://../rust/target/release/libgodot-fluent-translation.dylib"
macos.debug.arm64 = "res://../rust/target/debug/libgodot-fluent-translation.dylib"
macos.release.arm64 = "res://../rust/target/release/libgodot-fluent-translation.dylib"
linux.debug.x86_64 = "res://../rust/target/debug/libgodot_fluent_translation.so"
linux.release.x86_64 = "res://../rust/target/release/libgodot_fluent_translation.so"
windows.debug.x86_64 = "res://../rust/target/debug/godot_fluent_translation.dll"
windows.release.x86_64 = "res://../rust/target/release/godot_fluent_translation.dll"
macos.debug = "res://../rust/target/debug/libgodot_fluent_translation.dylib"
macos.release = "res://../rust/target/release/libgodot_fluent_translation.dylib"
macos.debug.arm64 = "res://../rust/target/debug/libgodot_fluent_translation.dylib"
macos.release.arm64 = "res://../rust/target/release/libgodot_fluent_translation.dylib"
27 changes: 14 additions & 13 deletions rust/src/fluent/extractor_packed_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl FluentTranslationParser for FluentPackedSceneTranslationParser {

// Parse the names of children of `TabContainer`s, as they are used for tab titles.
if !tabcontainer_paths.is_empty() {
if !parent_path.to_string().starts_with(&GString::from(tabcontainer_paths[((tabcontainer_paths.len() as i64) - 1) as usize].clone()).to_string()) {
if !parent_path.to_string().starts_with(&tabcontainer_paths[((tabcontainer_paths.len() as i64) - 1) as usize].clone().to_string()) {
// Switch to the previous `TabContainer` this was nested in, if that was the case.
tabcontainer_paths.pop();
}
Expand Down Expand Up @@ -145,17 +145,17 @@ impl FluentTranslationParser for FluentPackedSceneTranslationParser {
// Prevent reading text containing only spaces.
let str_value = GString::from_variant(&property_value);
if !str_value.to_string().trim().is_empty() {
parsed_strings.push(str_value.into());
parsed_strings.push(str_value);
}
}
}
}

// Assume that ids = messages.
return parsed_strings
parsed_strings
.into_iter()
.map(|string| (string.to_string(), string.to_string()))
.collect();
.collect()
}
}

Expand Down Expand Up @@ -183,18 +183,19 @@ impl FluentPackedSceneTranslationParser {

fn match_property(&self, property_name: &StringName, node_type: &StringName) -> bool {
let class_db = ClassDb::singleton();

for (exception_node_type, exception_properties) in &self.exception_list {
if class_db.is_parent_class(node_type.clone(), exception_node_type.clone()) {
if exception_properties.iter().any(|exception_property| Self::matches(GString::from(property_name), exception_property.clone())) {
return false;
}
if class_db.is_parent_class(node_type.clone(), exception_node_type.clone()) &&
exception_properties.iter().any(|exception_property|
Self::matches(GString::from(property_name), exception_property.clone())
) {
return false;
}
}
if self.lookup_properties.iter().any(|lookup_property| Self::matches(GString::from(property_name), lookup_property.clone())) {
return true;
}
return false;

self.lookup_properties.iter().any(|lookup_property|
Self::matches(GString::from(property_name), lookup_property.clone())
)
}

fn matches(string: GString, pattern: Gd<RegEx>) -> bool {
Expand Down
14 changes: 7 additions & 7 deletions rust/src/fluent/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl FluentGenerator {
pub fn create() -> Gd<Self> {
let project_settings = ProjectSettings::singleton();
let locales = PackedStringArray::from_variant(&project_settings.get_setting(PROJECT_SETTING_GENERATOR_LOCALES.into()));
let locales = locales.as_slice().into_iter().map(|s| s.to_string()).collect();
let locales = locales.as_slice().iter().map(|s| s.to_string()).collect();
let file_patterns = Dictionary::from_variant(&project_settings.get_setting(PROJECT_SETTING_GENERATOR_PATTERNS.into()));
let file_patterns = file_patterns.iter_shared().map(|(k, v)| {
let k = GString::from_variant(&k);
Expand All @@ -45,7 +45,7 @@ impl FluentGenerator {
}

#[func]
pub fn generate(&self) -> () {
pub fn generate(&self) {
// Collect source files and batched write operations.
let files = self.get_matching_files();
let mut generate_tasks = HashMap::<String, MessageGeneration>::new();
Expand All @@ -67,7 +67,7 @@ impl FluentGenerator {
return Some((safe_id, message));
}
}
return Some((id, message));
Some((id, message))
});
entry.or_default().extend(&mut messages);
}
Expand Down Expand Up @@ -102,7 +102,7 @@ impl FluentGenerator {
godot_warn!("File {str} matched generator rule \"{regex_str} -> {pattern}\" but has unrecognized extension {extension}, ignoring.");
return None;
}
return Some(regex_match);
Some(regex_match)
})
})
.collect()
Expand All @@ -112,7 +112,7 @@ impl FluentGenerator {
self.locales
.iter()
.map(|locale| {
let mut pattern = pattern.replace("{$locale}", &locale);
let mut pattern = pattern.replace("{$locale}", locale);
for group_index in 0..=source_match.get_group_count() {
let group_value = source_match.get_string_ex().name(group_index.to_variant()).done();
pattern = pattern.replace(&format!("{{${}}}", group_index), &group_value.to_string());
Expand All @@ -123,7 +123,7 @@ impl FluentGenerator {
.collect()
}

fn create_or_update_ftl(path: String, messages: MessageGeneration) -> () {
fn create_or_update_ftl(path: String, messages: MessageGeneration) {
// Load existing or create new FTL file.
let fa = create_or_open_file_for_read_write(path.clone().into());
if fa.is_err() {
Expand Down Expand Up @@ -234,4 +234,4 @@ impl FluentGenerator {

new_name
}
}
}
2 changes: 1 addition & 1 deletion rust/src/fluent/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ impl FluentI18nSingleton {
pub(crate) fn unregister(&self) {
ResourceLoader::singleton().remove_resource_format_loader(self.loader.clone().upcast());
}
}
}
2 changes: 1 addition & 1 deletion rust/src/fluent/locale.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@ fn is_valid_locale(locale: &str) -> bool {

let identifier = locale.parse::<LanguageIdentifier>();
identifier.is_ok()
}
}
26 changes: 13 additions & 13 deletions rust/src/fluent/project_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,33 @@ use godot::prelude::*;
use godot::engine::ProjectSettings;
use constcat::concat as constcat;

const PROJECT_SETTING_PREFIX: &'static str = "internationalization/fluent/";
pub(crate) const PROJECT_SETTING_FALLBACK_LOCALE: &'static str = "internationalization/locale/fallback";
pub(crate) const PROJECT_SETTING_PARSE_ARGS_IN_MESSAGE: &'static str = constcat!(PROJECT_SETTING_PREFIX, "parse_args_in_message");
pub(crate) const PROJECT_SETTING_LOCALE_BY_FOLDER_REGEX: &'static str = constcat!(PROJECT_SETTING_PREFIX, "locale_by_folder_regex");
pub(crate) const PROJECT_SETTING_LOCALE_BY_FILE_REGEX: &'static str = constcat!(PROJECT_SETTING_PREFIX, "locale_by_file_regex");
pub(crate) const PROJECT_SETTING_GENERATOR_LOCALES: &'static str = constcat!(PROJECT_SETTING_PREFIX, "generator/locales");
pub(crate) const PROJECT_SETTING_GENERATOR_PATTERNS: &'static str = constcat!(PROJECT_SETTING_PREFIX, "generator/file_patterns");
pub(crate) const PROJECT_SETTING_GENERATOR_INVALID_MESSAGE_HANDLING: &'static str = constcat!(PROJECT_SETTING_PREFIX, "generator/invalid_message_handling");
const PROJECT_SETTING_PREFIX: &str = "internationalization/fluent/";
pub(crate) const PROJECT_SETTING_FALLBACK_LOCALE: &str = "internationalization/locale/fallback";
pub(crate) const PROJECT_SETTING_PARSE_ARGS_IN_MESSAGE: &str = constcat!(PROJECT_SETTING_PREFIX, "parse_args_in_message");
pub(crate) const PROJECT_SETTING_LOCALE_BY_FOLDER_REGEX: &str = constcat!(PROJECT_SETTING_PREFIX, "locale_by_folder_regex");
pub(crate) const PROJECT_SETTING_LOCALE_BY_FILE_REGEX: &str = constcat!(PROJECT_SETTING_PREFIX, "locale_by_file_regex");
pub(crate) const PROJECT_SETTING_GENERATOR_LOCALES: &str = constcat!(PROJECT_SETTING_PREFIX, "generator/locales");
pub(crate) const PROJECT_SETTING_GENERATOR_PATTERNS: &str = constcat!(PROJECT_SETTING_PREFIX, "generator/file_patterns");
pub(crate) const PROJECT_SETTING_GENERATOR_INVALID_MESSAGE_HANDLING: &str = constcat!(PROJECT_SETTING_PREFIX, "generator/invalid_message_handling");

pub(crate) const INVALID_MESSAGE_HANDLING_SKIP: i32 = 0;
pub(crate) const INVALID_MESSAGE_HANDLING_CONVERT_TO_VALID: i32 = 1;

pub fn register() -> () {
pub fn register() {
// Default to true for default builds (no args parameter), false for forked builds.
register_setting(PROJECT_SETTING_PARSE_ARGS_IN_MESSAGE.to_string(), cfg!(not(feature = "forked-godot")).to_variant());
register_setting(PROJECT_SETTING_LOCALE_BY_FOLDER_REGEX.to_string(), "^.+$".to_variant());
register_setting(PROJECT_SETTING_LOCALE_BY_FILE_REGEX.to_string(), "\\.(.+?)\\.ftl$".to_variant());
register_setting_hint(PROJECT_SETTING_GENERATOR_LOCALES.to_string(), PackedStringArray::new().to_variant(), PropertyHint::NONE, format!("{}/{}:", VariantType::String as i32, PropertyHint::LOCALE_ID.ord()).into());
register_setting_hint(PROJECT_SETTING_GENERATOR_LOCALES.to_string(), PackedStringArray::new().to_variant(), PropertyHint::NONE, format!("{}/{}:", VariantType::String as i32, PropertyHint::LOCALE_ID.ord()));
register_setting(PROJECT_SETTING_GENERATOR_PATTERNS.to_string(), Dictionary::new().to_variant());
register_setting_hint(PROJECT_SETTING_GENERATOR_INVALID_MESSAGE_HANDLING.to_string(), 0.to_variant(), PropertyHint::ENUM, "Skip message,Convert to valid".into());
}

fn register_setting(name: String, value: Variant) -> () {
fn register_setting(name: String, value: Variant) {
register_setting_hint(name, value, PropertyHint::NONE, String::new());
}

fn register_setting_hint(name: String, value: Variant, hint: PropertyHint, hint_string: String) -> () {
fn register_setting_hint(name: String, value: Variant, hint: PropertyHint, hint_string: String) {
let mut project_settings = ProjectSettings::singleton();

if !project_settings.has_setting(name.clone().into()) {
Expand All @@ -44,4 +44,4 @@ fn register_setting_hint(name: String, value: Variant, hint: PropertyHint, hint_

project_settings.add_property_info(property_info);
project_settings.set_initial_value(GString::from(name), value);
}
}
14 changes: 4 additions & 10 deletions rust/src/fluent/translation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,9 @@ impl TranslationFluent {

let result = bundles
.iter()
.map(|bundle| {
.filter_map(|bundle| {
Self::translate(bundle, &msg, &args.clone(), if context.is_empty() { None } else { Some(&context) })
})
.filter(|v| v.is_some())
.map(|v| v.unwrap())
.next();

match result {
Expand Down Expand Up @@ -153,9 +151,7 @@ impl TranslationFluent {

pub fn translate(bundle: &FluentBundle<FluentResource>, message_id: &StringName, args: &Dictionary, attribute: Option<&StringName>) -> Option<String> {
let message = bundle.get_message(&String::from(message_id));
if message.is_none() {
return None;
}
message.as_ref()?;
let message = message.unwrap();
let pattern = match attribute {
Some(attribute) => {
Expand All @@ -164,9 +160,7 @@ impl TranslationFluent {
},
None => message.value(),
};
if pattern.is_none() {
return None;
}
pattern?;
let pattern = pattern.unwrap();
let mut errors = vec![];
let args = Self::dict_to_args(args);
Expand Down Expand Up @@ -248,4 +242,4 @@ impl TranslationFluent {
}
}
}
}
}
6 changes: 3 additions & 3 deletions rust/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ pub fn create_or_open_file_for_read_write(path: GString) -> Result<Gd<FileAccess
return Err(dir_err);
}

let fa = FileAccess::open(path.clone().into(), ModeFlags::READ_WRITE);
let fa = FileAccess::open(path.clone(), ModeFlags::READ_WRITE);
if fa.is_none() || FileAccess::get_open_error() != GdErr::OK {
if FileAccess::get_open_error() == GdErr::ERR_FILE_NOT_FOUND {
let fa = FileAccess::open(path.clone().into(), ModeFlags::WRITE_READ);
let fa = FileAccess::open(path.clone(), ModeFlags::WRITE_READ);
if fa.is_some() && FileAccess::get_open_error() == GdErr::OK {
return Ok(fa.unwrap());
}
}
return Err(FileAccess::get_open_error());
}
return Ok(fa.unwrap());
Ok(fa.unwrap())
}