diff --git a/BeefBuild/src/BuildApp.bf b/BeefBuild/src/BuildApp.bf index 3df43045..4f5de7ff 100644 --- a/BeefBuild/src/BuildApp.bf +++ b/BeefBuild/src/BuildApp.bf @@ -113,6 +113,7 @@ namespace BeefBuild { mWorkspace.mName = new String(); Path.GetFileName(mWorkspace.mDir, mWorkspace.mName); + CustomBuildProperties.Load(false); LoadWorkspace(mVerb); } else @@ -306,6 +307,27 @@ namespace BeefBuild if (mPackMan.mCleanHashSet.TryAddAlt(value, var entryPtr)) *entryPtr = new .(value); return true; + case "-property": + int splitIdx = (int)value.IndexOf('='); + if (splitIdx != -1) + { + String propertyName = new String(); + StringView propertyKeyView = value.Substring(0, splitIdx); + propertyKeyView.ToString(propertyName); + + String propertyValue = new String(); + StringView propertyValueView = value.Substring(splitIdx + 1, value.Length - splitIdx - 1); + propertyValueView.ToString(propertyValue); + + if (!CustomBuildProperties.TryAddProperty(propertyName, propertyValue)) + { + delete propertyName; + delete propertyValue; + return false; + } + + return true; + } } } diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 7796a9e1..78747d14 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -1027,6 +1027,12 @@ namespace IDE AddBuildFileDependency(project.mWindowsOptions.mIconFile); AddBuildFileDependency(project.mWindowsOptions.mManifestFile); + String fileVersion = scope String(); + gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, project.mWindowsOptions.mFileVersion, "file version", fileVersion); + + String productVersion = scope String(); + gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, project.mWindowsOptions.mProductVersion, "product version", productVersion); + switch (mPlatformType) { case .Windows: @@ -1035,8 +1041,8 @@ namespace IDE cacheStr.AppendF("Company\t{}\n", project.mWindowsOptions.mCompany); cacheStr.AppendF("Product\t{}\n", project.mWindowsOptions.mProduct); cacheStr.AppendF("Copyright\t{}\n", project.mWindowsOptions.mCopyright); - cacheStr.AppendF("FileVersion\t{}\n", project.mWindowsOptions.mFileVersion); - cacheStr.AppendF("ProductVersion\t{}\n", project.mWindowsOptions.mProductVersion); + cacheStr.AppendF("FileVersion\t{}\n", fileVersion); + cacheStr.AppendF("ProductVersion\t{}\n", productVersion); case .Linux: cacheStr.AppendF("Options\t{}\n", project.mLinuxOptions.mOptions); case .Wasm: @@ -1265,11 +1271,17 @@ namespace IDE } } + String fileVersion = scope String(); + gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, winOptions.mFileVersion, "file version", fileVersion); + + String productVersion = scope String(); + gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, winOptions.mProductVersion, "product version", productVersion); + let targetFileName = scope String(); Path.GetFileName(targetPath, targetFileName); if (resGen.AddVersion(winOptions.mDescription, winOptions.mComments, winOptions.mCompany, winOptions.mProduct, - winOptions.mCopyright, winOptions.mFileVersion, winOptions.mProductVersion, targetFileName) case .Err) + winOptions.mCopyright, fileVersion, productVersion, targetFileName) case .Err) { gApp.OutputErrorLine("Failed to add version"); return .Err; diff --git a/IDE/src/CustomBuildProperties.bf b/IDE/src/CustomBuildProperties.bf new file mode 100644 index 00000000..ec66fbc2 --- /dev/null +++ b/IDE/src/CustomBuildProperties.bf @@ -0,0 +1,99 @@ +using System; +using System.Collections; +using System.IO; +using System.Reflection; +using Beefy.utils; + +namespace IDE +{ + class CustomBuildProperties + { + static Dictionary mProperties = new .() ~ DeleteDictionaryAndKeysAndValues!(_); + + static public void GetFileName(String outResult) + { + String workspaceDir = scope String(); + + if (gApp.mWorkspace.mDir == null) + Directory.GetCurrentDirectory(workspaceDir); + else + workspaceDir = gApp.mWorkspace.mDir; + + outResult.Append(workspaceDir, "/BeefProperties.toml"); + } + + static public void Clear() + { + for (var entry in mProperties) + { + delete entry.key; + delete entry.value; + } + + mProperties.Clear(); + } + + static public void Load(bool clearExistingProperties = true) + { + const char8* PROPERTIES_STR = "Properties"; + + if (clearExistingProperties) + Clear(); + + String propertiesFileName = scope String(); + GetFileName(propertiesFileName); + + if (!File.Exists(propertiesFileName)) + return; + + StructuredData data = scope StructuredData(); + if (gApp.StructuredLoad(data, propertiesFileName) case .Err(let err)) + { + gApp.OutputErrorLine("Failed to load properties from: '{0}'", propertiesFileName); + return; + } + + if (!data.Contains(PROPERTIES_STR)) + return; + + for (var property in data.Enumerate(PROPERTIES_STR)) + { + String propertyName = new String(); + property.ToString(propertyName); + + if (Contains(propertyName)) + { + delete propertyName; + continue; + } + + String propertyValue = new String(); + data.GetCurString(propertyValue); + + TryAddProperty(propertyName, propertyValue); + } + } + + static public bool TryAddProperty(String propertyName, String propertyValue) + { + if (Contains(propertyName)) + return false; + + mProperties.Add(propertyName, propertyValue); + return true; + } + + static public bool Contains(String property) + { + return mProperties.ContainsKey(property); + } + + static public String Get(String property) + { + if (!Contains(property)) + return null; + + return mProperties[property]; + } + } +} diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 55033a0e..ff334715 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -984,6 +984,7 @@ namespace IDE mWorkspace.mName = new String(); Path.GetFileName(mWorkspace.mDir, mWorkspace.mName); + CustomBuildProperties.Load(); LoadWorkspace(.OpenOrNew); FinishShowingNewWorkspace(); } @@ -3191,6 +3192,7 @@ namespace IDE CloseWorkspace(); mWorkspace.mDir = new String(workspaceDir); mWorkspace.mName = new String(workspaceName); + CustomBuildProperties.Load(); LoadWorkspace(.Open); FinishShowingNewWorkspace(); } @@ -3320,7 +3322,13 @@ namespace IDE switch (useVerSpec) { case .Path(let path): - var relPath = scope String(path); + Project.Options options = GetCurProjectOptions(project); + Workspace.Options workspaceOptions = GetCurWorkspaceOptions(); + + var resolvedPath = scope String(); + ResolveConfigString(mPlatformName, workspaceOptions, project, options, path, "project path", resolvedPath); + + var relPath = scope String(resolvedPath); IDEUtils.FixFilePath(relPath); if (!relPath.EndsWith(IDEUtils.cNativeSlash)) relPath.Append(IDEUtils.cNativeSlash); @@ -10961,6 +10969,12 @@ namespace IDE case "BeefPath": newString = gApp.mInstallDir; default: + // Check if any custom properties match the string. + if (CustomBuildProperties.Contains(replaceStr)) + { + newString = scope:ReplaceBlock String(); + newString.Append(CustomBuildProperties.Get(replaceStr)); + } } } @@ -12869,12 +12883,14 @@ namespace IDE { mWorkspace.mName = new String(); Path.GetFileName(mWorkspace.mDir, mWorkspace.mName); + CustomBuildProperties.Load(); LoadWorkspace(mVerb); } else if (mWorkspace.IsSingleFileWorkspace) { mWorkspace.mName = new String(); Path.GetFileNameWithoutExtension(mWorkspace.mCompositeFile.mFilePath, mWorkspace.mName); + CustomBuildProperties.Load(); LoadWorkspace(mVerb); } diff --git a/IDE/src/ui/NewProjectDialog.bf b/IDE/src/ui/NewProjectDialog.bf index 47f3de5c..a327ab59 100644 --- a/IDE/src/ui/NewProjectDialog.bf +++ b/IDE/src/ui/NewProjectDialog.bf @@ -142,7 +142,8 @@ namespace IDE.ui DeleteAndNullify!(app.mWorkspace.mDir); app.mWorkspace.mDir = new String(projDirectory); app.mWorkspace.mName = new String(projName); - + + CustomBuildProperties.Load(); app.[Friend]LoadWorkspace(.OpenOrNew); app.[Friend]FinishShowingNewWorkspace(false);