Repository: microsoft/terminal (language: cpp)

Issue:
Terminal Preview settings file references the Stable schema
The settings schema 1.0 doesn't have "compact" option for the tabWidthMode setting.
Terminal Preview 1.1.1671.0 references https://raw.githubusercontent.com/microsoft/terminal/release-1.0/doc/cascadia/profiles.schema.json Now when the terminal preview and the stable versions have diverged, it appears that schema needs to diverge as well.


Discussion / hints:
I'm not sure there's a good way for us to differentiate the two. We could change the aka.ms link to point at a different location for the preview build, but then users who just copy-paste their settings over from the release to the preview version would lose the preview URL. Hmmmmm
@zadjii-msft I'd say that blindly copy-pasting stuff, especially configs of different versions of an app isn't the best thing in the world :) What about building in a "settings import tool" into the Terminal which would fix the schema upon importing (potentially among other things)? Or a settings migration tool. It would probably sit well within the future Settings UI. It may be a bit of an overkill though...
This is definitely something we'll need some code to back up, too. Ugh. Thank you.
> I'm not sure there's a good way for us to differentiate the two. We could change the aka.ms link to point at a different location for the preview build, but then users who just copy-paste their settings over from the release to the preview version would lose the preview URL. Hmmmmm

I'd say it's better to have the schema-url to automatically follow the channel via which it is created
A brainblast I had while responding to #7341 - what if we had two aka.ms links, one for the preview and one for the stable schemas. When we lay down the userDefaults.json, let's stomp in the appropriate URL. 

People currently on preview would need to update the URL manually, but that's not too bad. Current stable users would still get the stable schema, and new preview users would get the preview one.


I've apparently had this thought before, but now that it's a new day, I'm gonna say _this is fine_. 
https://raw.githubusercontent.com/microsoft/terminal/master/doc/cascadia/profiles.schema.json contains the latest and greatest schema as it gets updated. But the `alwaysOnTop`, `largePasteWarning` and `multiLinePasteWarning` properties are considered "not allowed".  I don't see an issue for that so I'll raise one. 

Update: https://github.com/microsoft/terminal/issues/7353 filed.

Update 2: Apparently global settings aren't supposed to go under "defaults" but rather above it. But that's rather unorganized to me.
Why not do something more on the lines of:

- if non-preview, then use schema as "https://aka.ms/terminal-profiles-schema"
- if preview, then use schema as "https://raw.githubusercontent.com/microsoft/terminal/TAG/doc/cascadia/profiles.schema.json", replacing tag with current app version (matching the GitHub tag)
I like the idea of a dynamic `userDefaults.json` but is that something better addressed in the Settings UI effort?
In the meantime, since everyone must modify their `settings.json` directly anyway, here's my stopgap thought for `userDefaults.json`:

```
{
    // In order to receive the correct schema, comment/uncomment the $schema below according to the release you have installed.

    // Stable Release:
    "$schema": "https://aka.ms/terminal-profiles-schema",

    // Preview Release:
    // "$schema": "https://aka.ms/terminal-profiles-schema-preview",
```

Maybe someone else can wordsmith the first comment better? I can't tell if I made it too wordy.

The preview schema link can be:

- A new aka.ms link such as the example in the code block above (preferred)
  - Someone or something is updating the current aka.ms link destination as it currently points to the latest stable  https://raw.githubusercontent.com/microsoft/terminal/release-1.4/doc/cascadia/profiles.schema.json
  - The same update would naturally need to take place for the latest preview https://raw.githubusercontent.com/microsoft/terminal/release-1.5/doc/cascadia/profiles.schema.json
- A direct link to the latest preview release of `profiles.schema.json`
  - Would require manually updating `userDefaults.json` with each release https://raw.githubusercontent.com/microsoft/terminal/release-1.5/doc/cascadia/profiles.schema.json
- A direct link to the latest merged `profiles.schema.json`
  - Would not require manually updating `userDefaults.json`, but at times preview users may see settings referenced that haven't been released to them yet https://raw.githubusercontent.com/microsoft/terminal/main/doc/cascadia/profiles.schema.json
Yeah, and the user settings can be automatically edited to use the correct schema based on the last wt version that was opened, so If I had WT-Preview running then it can change the schema URL to the shortlik for preview schema. If I had WT-Release running, the JSON is automatically edited so It points to the release schema.
That's for sure the ideal implementation. But I'm wondering if that effort should simply be a part of the broader full blown Settings UI feature. In the meantime what I suggested would still be a manual effort, but at least both links would be available in `userDefaults.json` and it'd be clear to users which link they need to use (since everyone already has to open up their `settings.json` to configure any settings already).

I don't want to cause any unnecessary scope creep on whomever is working on the Settings UI though 😁 imo there needs to be some level of concurrence here since no matter how you approach this particular issue, there's broader implications for other features in the works.
> Why not do something more on the lines of:
> 
> * if non-preview, then use schema as "[aka.ms/terminal-profiles-schema](https://aka.ms/terminal-profiles-schema)"
> * if preview, then use schema as "[`TAG`/doc/cascadia/profiles.schema.json (raw)](https://raw.githubusercontent.com/microsoft/terminal/TAG/doc/cascadia/profiles.schema.json)", replacing tag with current app version (matching the GitHub tag)

The problem of using the `main` branch is that it might have schema that has not yet been released.
If there were `release` and a `prerelease` branches the aka.ms links would be unnecessary, we could just use a raw.githubusercontent url directly pointing to the `profiles.schema.json` at the specific branch. `main` should only be used for the ones building Terminal themselves (I was one of those and I used `main` for years).

To the team: do you think that having such branches makes sense?

Fix patch:
diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp
index 542b4b8398d..3063f549494 100644
--- a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp
+++ b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp
@@ -1227,6 +1227,15 @@ void CascadiaSettings::WriteSettingsToDisk()
     }
 }
 
+#ifndef NDEBUG
+static [[maybe_unused]] std::string _getDevPathToSchema()
+{
+    std::filesystem::path filePath{ __FILE__ };
+    auto schemaPath = filePath.parent_path().parent_path().parent_path().parent_path() / "doc" / "cascadia" / "profiles.schema.json";
+    return "file:///" + schemaPath.generic_string();
+}
+#endif
+
 // Method Description:
 // - Create a new serialized JsonObject from an instance of this class
 // Arguments:
@@ -1238,7 +1247,17 @@ Json::Value CascadiaSettings::ToJson() const
     // top-level json object
     auto json{ _globals->ToJson() };
     json["$help"] = "https://aka.ms/terminal-documentation";
-    json["$schema"] = "https://aka.ms/terminal-profiles-schema";
+    json["$schema"] =
+#if defined(WT_BRANDING_RELEASE)
+        "https://aka.ms/terminal-profiles-schema"
+#elif defined(WT_BRANDING_PREVIEW)
+        "https://aka.ms/terminal-profiles-schema-preview"
+#elif !defined(NDEBUG) // DEBUG mode
+        _getDevPathToSchema() // magic schema path that refers to the local source directory
+#else // All other brandings
+        "https://raw.githubusercontent.com/microsoft/terminal/main/doc/cascadia/profiles.schema.json"
+#endif
+        ;
 
     // "profiles" will always be serialized as an object
     Json::Value profiles{ Json::ValueType::objectValue };


Test patch: