C#: Unify project name handling and fix issues with the handling of some special characters
Co-authored-by: Raul Santos <raulsntos@gmail.com>
This commit is contained in:
parent
33957aee69
commit
92f13ba9ea
|
@ -67,14 +67,6 @@ String ProjectSettings::get_resource_path() const {
|
|||
return resource_path;
|
||||
}
|
||||
|
||||
String ProjectSettings::get_safe_project_name() const {
|
||||
String safe_name = OS::get_singleton()->get_safe_dir_name(get("application/config/name"));
|
||||
if (safe_name.is_empty()) {
|
||||
safe_name = "UnnamedProject";
|
||||
}
|
||||
return safe_name;
|
||||
}
|
||||
|
||||
String ProjectSettings::get_imported_files_path() const {
|
||||
return get_project_data_path().path_join("imported");
|
||||
}
|
||||
|
@ -930,10 +922,26 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const RBMap<Str
|
|||
}
|
||||
|
||||
Error ProjectSettings::_save_custom_bnd(const String &p_file) { // add other params as dictionary and array?
|
||||
|
||||
return save_custom(p_file);
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
bool _csproj_exists(String p_root_dir) {
|
||||
Ref<DirAccess> dir = DirAccess::open(p_root_dir);
|
||||
|
||||
dir->list_dir_begin();
|
||||
String file_name = dir->_get_next();
|
||||
while (file_name != "") {
|
||||
if (!dir->current_is_dir() && file_name.get_extension() == "csproj") {
|
||||
return true;
|
||||
}
|
||||
file_name = dir->_get_next();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_custom, const Vector<String> &p_custom_features, bool p_merge_with_current) {
|
||||
ERR_FAIL_COND_V_MSG(p_path.is_empty(), ERR_INVALID_PARAMETER, "Project settings save path cannot be empty.");
|
||||
|
||||
|
@ -952,7 +960,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
|
|||
}
|
||||
}
|
||||
// Check for the existence of a csproj file.
|
||||
if (FileAccess::exists(get_resource_path().path_join(get_safe_project_name() + ".csproj"))) {
|
||||
if (_csproj_exists(get_resource_path())) {
|
||||
// If there is a csproj file, add the C# feature if it doesn't already exist.
|
||||
if (!project_features.has("C#")) {
|
||||
project_features.append("C#");
|
||||
|
|
|
@ -166,7 +166,6 @@ public:
|
|||
String get_project_data_dir_name() const;
|
||||
String get_project_data_path() const;
|
||||
String get_resource_path() const;
|
||||
String get_safe_project_name() const;
|
||||
String get_imported_files_path() const;
|
||||
|
||||
static ProjectSettings *get_singleton();
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "signal_awaiter_utils.h"
|
||||
#include "utils/macros.h"
|
||||
#include "utils/naming_utils.h"
|
||||
#include "utils/path_utils.h"
|
||||
#include "utils/string_utils.h"
|
||||
|
||||
#define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->get_string_names().m_var)
|
||||
|
@ -740,11 +741,7 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
|
|||
return false; // Already up to date
|
||||
}
|
||||
} else {
|
||||
String assembly_name = GLOBAL_GET("dotnet/project/assembly_name");
|
||||
|
||||
if (assembly_name.is_empty()) {
|
||||
assembly_name = ProjectSettings::get_singleton()->get_safe_project_name();
|
||||
}
|
||||
String assembly_name = path::get_csharp_project_name();
|
||||
|
||||
assembly_path = GodotSharpDirs::get_res_temp_assemblies_dir()
|
||||
.path_join(assembly_name + ".dll");
|
||||
|
|
|
@ -57,27 +57,5 @@ namespace GodotTools.Core
|
|||
path.StartsWith("\\", StringComparison.Ordinal) ||
|
||||
path.StartsWith(_driveRoot, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static string ToSafeDirName(this string dirName, bool allowDirSeparator = false)
|
||||
{
|
||||
var invalidChars = new List<string> { ":", "*", "?", "\"", "<", ">", "|" };
|
||||
|
||||
if (allowDirSeparator)
|
||||
{
|
||||
// Directory separators are allowed, but disallow ".." to avoid going up the filesystem
|
||||
invalidChars.Add("..");
|
||||
}
|
||||
else
|
||||
{
|
||||
invalidChars.Add("/");
|
||||
}
|
||||
|
||||
string safeDirName = dirName.Replace("\\", "/").Trim();
|
||||
|
||||
foreach (string invalidChar in invalidChars)
|
||||
safeDirName = safeDirName.Replace(invalidChar, "-");
|
||||
|
||||
return safeDirName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ namespace GodotTools.Export
|
|||
string ridOS = DetermineRuntimeIdentifierOS(platform);
|
||||
string ridArch = DetermineRuntimeIdentifierArch(arch);
|
||||
string runtimeIdentifier = $"{ridOS}-{ridArch}";
|
||||
string projectDataDirName = $"{DetermineDataDirNameForProject()}_{arch}";
|
||||
string projectDataDirName = $"data_{GodotSharpDirs.CSharpProjectName}_{arch}";
|
||||
if (platform == OS.Platforms.MacOS)
|
||||
{
|
||||
projectDataDirName = Path.Combine("Contents", "Resources", projectDataDirName);
|
||||
|
@ -258,12 +258,5 @@ namespace GodotTools.Export
|
|||
platform = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string DetermineDataDirNameForProject()
|
||||
{
|
||||
string appName = (string)ProjectSettings.GetSetting("application/config/name");
|
||||
string appNameSafe = appName.ToSafeDirName();
|
||||
return $"data_{appNameSafe}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,21 +48,23 @@ namespace GodotTools.Internals
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static string CSharpProjectName
|
||||
{
|
||||
get
|
||||
{
|
||||
Internal.godot_icall_GodotSharpDirs_CSharpProjectName(out godot_string dest);
|
||||
using (dest)
|
||||
return Marshaling.ConvertStringToManaged(dest);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DetermineProjectLocation()
|
||||
{
|
||||
static string DetermineProjectName()
|
||||
{
|
||||
string projectAssemblyName = (string)ProjectSettings.GetSetting("application/config/name");
|
||||
projectAssemblyName = projectAssemblyName.ToSafeDirName();
|
||||
if (string.IsNullOrEmpty(projectAssemblyName))
|
||||
projectAssemblyName = "UnnamedProject";
|
||||
return projectAssemblyName;
|
||||
}
|
||||
|
||||
_projectAssemblyName = (string)ProjectSettings.GetSetting("dotnet/project/assembly_name");
|
||||
if (string.IsNullOrEmpty(_projectAssemblyName))
|
||||
{
|
||||
_projectAssemblyName = DetermineProjectName();
|
||||
_projectAssemblyName = CSharpProjectName;
|
||||
ProjectSettings.SetSetting("dotnet/project/assembly_name", _projectAssemblyName);
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,8 @@ namespace GodotTools.Internals
|
|||
|
||||
public static partial void godot_icall_GodotSharpDirs_DataEditorToolsDir(out godot_string r_dest);
|
||||
|
||||
public static partial void godot_icall_GodotSharpDirs_CSharpProjectName(out godot_string r_dest);
|
||||
|
||||
public static partial void godot_icall_EditorProgress_Create(in godot_string task, in godot_string label,
|
||||
int amount, bool canCancel);
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "../csharp_script.h"
|
||||
#include "../godotsharp_dirs.h"
|
||||
#include "../utils/macos_utils.h"
|
||||
#include "../utils/path_utils.h"
|
||||
#include "code_completion.h"
|
||||
|
||||
#include "../interop_types.h"
|
||||
|
@ -81,6 +82,10 @@ void godot_icall_GodotSharpDirs_DataEditorToolsDir(godot_string *r_dest) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void godot_icall_GodotSharpDirs_CSharpProjectName(godot_string *r_dest) {
|
||||
memnew_placement(r_dest, String(path::get_csharp_project_name()));
|
||||
}
|
||||
|
||||
void godot_icall_EditorProgress_Create(const godot_string *p_task, const godot_string *p_label, int32_t p_amount, bool p_can_cancel) {
|
||||
String task = *reinterpret_cast<const String *>(p_task);
|
||||
String label = *reinterpret_cast<const String *>(p_label);
|
||||
|
@ -231,6 +236,7 @@ static const void *unmanaged_callbacks[]{
|
|||
(void *)godot_icall_GodotSharpDirs_MonoUserDir,
|
||||
(void *)godot_icall_GodotSharpDirs_BuildLogsDirs,
|
||||
(void *)godot_icall_GodotSharpDirs_DataEditorToolsDir,
|
||||
(void *)godot_icall_GodotSharpDirs_CSharpProjectName,
|
||||
(void *)godot_icall_EditorProgress_Create,
|
||||
(void *)godot_icall_EditorProgress_Dispose,
|
||||
(void *)godot_icall_EditorProgress_Step,
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#endif
|
||||
|
||||
#include "mono_gd/gd_mono.h"
|
||||
#include "utils/path_utils.h"
|
||||
|
||||
namespace GodotSharpDirs {
|
||||
|
||||
|
@ -139,8 +140,7 @@ private:
|
|||
api_assemblies_dir = api_assemblies_base_dir.path_join(GDMono::get_expected_api_build_config());
|
||||
#else // TOOLS_ENABLED
|
||||
String arch = Engine::get_singleton()->get_architecture_name();
|
||||
String appname = GLOBAL_GET("application/config/name");
|
||||
String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
|
||||
String appname_safe = path::get_csharp_project_name();
|
||||
String data_dir_root = exe_dir.path_join("data_" + appname_safe + "_" + arch);
|
||||
if (!DirAccess::exists(data_dir_root)) {
|
||||
data_dir_root = exe_dir.path_join("data_Godot_" + arch);
|
||||
|
|
|
@ -293,20 +293,10 @@ godot_plugins_initialize_fn initialize_hostfxr_and_godot_plugins(bool &r_runtime
|
|||
return godot_plugins_initialize;
|
||||
}
|
||||
#else
|
||||
static String get_assembly_name() {
|
||||
String assembly_name = GLOBAL_GET("dotnet/project/assembly_name");
|
||||
|
||||
if (assembly_name.is_empty()) {
|
||||
assembly_name = ProjectSettings::get_singleton()->get_safe_project_name();
|
||||
}
|
||||
|
||||
return assembly_name;
|
||||
}
|
||||
|
||||
godot_plugins_initialize_fn initialize_hostfxr_and_godot_plugins(bool &r_runtime_initialized) {
|
||||
godot_plugins_initialize_fn godot_plugins_initialize = nullptr;
|
||||
|
||||
String assembly_name = get_assembly_name();
|
||||
String assembly_name = path::get_csharp_project_name();
|
||||
|
||||
HostFxrCharString assembly_path = str_to_hostfxr(GodotSharpDirs::get_api_assemblies_dir()
|
||||
.path_join(assembly_name + ".dll"));
|
||||
|
@ -331,7 +321,7 @@ godot_plugins_initialize_fn initialize_hostfxr_and_godot_plugins(bool &r_runtime
|
|||
}
|
||||
|
||||
godot_plugins_initialize_fn try_load_native_aot_library(void *&r_aot_dll_handle) {
|
||||
String assembly_name = get_assembly_name();
|
||||
String assembly_name = path::get_csharp_project_name();
|
||||
|
||||
#if defined(WINDOWS_ENABLED)
|
||||
String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().path_join(assembly_name + ".dll");
|
||||
|
@ -476,11 +466,7 @@ void GDMono::_init_godot_api_hashes() {
|
|||
|
||||
#ifdef TOOLS_ENABLED
|
||||
bool GDMono::_load_project_assembly() {
|
||||
String assembly_name = GLOBAL_GET("dotnet/project/assembly_name");
|
||||
|
||||
if (assembly_name.is_empty()) {
|
||||
assembly_name = ProjectSettings::get_singleton()->get_safe_project_name();
|
||||
}
|
||||
String assembly_name = path::get_csharp_project_name();
|
||||
|
||||
String assembly_path = GodotSharpDirs::get_res_temp_assemblies_dir()
|
||||
.path_join(assembly_name + ".dll");
|
||||
|
|
|
@ -231,4 +231,27 @@ String relative_to(const String &p_path, const String &p_relative_to) {
|
|||
|
||||
return relative_to_impl(path_abs_norm, relative_to_abs_norm);
|
||||
}
|
||||
|
||||
String get_csharp_project_name() {
|
||||
String name = ProjectSettings::get_singleton()->get_setting_with_override("dotnet/project/assembly_name");
|
||||
if (name.is_empty()) {
|
||||
name = ProjectSettings::get_singleton()->get_setting_with_override("application/config/name");
|
||||
Vector<String> invalid_chars = Vector<String>({ //
|
||||
// Windows reserved filename chars.
|
||||
":", "*", "?", "\"", "<", ">", "|",
|
||||
// Directory separators.
|
||||
"/", "\\",
|
||||
// Other chars that have been found to break assembly loading.
|
||||
";", "'", "=", "," });
|
||||
name = name.strip_edges();
|
||||
for (int i = 0; i < invalid_chars.size(); i++) {
|
||||
name = name.replace(invalid_chars[i], "-");
|
||||
}
|
||||
}
|
||||
if (name.is_empty()) {
|
||||
name = "UnnamedProject";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
} // namespace path
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#ifndef MONO_PATH_UTILS_H
|
||||
#define MONO_PATH_UTILS_H
|
||||
|
||||
#include "core/string/string_builder.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
||||
namespace path {
|
||||
|
@ -58,6 +57,8 @@ String abspath(const String &p_path);
|
|||
String realpath(const String &p_path);
|
||||
|
||||
String relative_to(const String &p_path, const String &p_relative_to);
|
||||
|
||||
String get_csharp_project_name();
|
||||
} // namespace path
|
||||
|
||||
#endif // MONO_PATH_UTILS_H
|
||||
|
|
Loading…
Reference in New Issue