Repository: microsoft/terminal
File: src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp (C++)

Code before:
        if (std::filesystem::is_directory(protoExtFolder) && ignoredNamespaces.find(source) == ignoredNamespaces.end())
        {
            const auto jsonFiles = _AccumulateJsonFilesInDirectory(protoExtFolder.path().c_str());
            _AddOrModifyProfiles(jsonFiles, winrt::hstring{ source });
        }
    }
}

// Method Description:
// - Finds all the json files within the given directory
// Arguments:
// - directory: the directory to search
// Return Value:
// - A set containing all the found file data
std::unordered_set<std::string> CascadiaSettings::_AccumulateJsonFilesInDirectory(const std::wstring_view directory)
{
    std::unordered_set<std::string> jsonFiles;

    // Expand out environment strings like %LOCALAPPDATA% and %ProgramData%
    const std::filesystem::path root{ wil::ExpandEnvironmentStringsW<std::wstring>(directory.data()) };

    for (auto& protoExt : std::filesystem::directory_iterator(root))
    {
        if (protoExt.path().extension() == jsonExtension)
        {
            wil::unique_hfile hFile{ CreateFileW(protoExt.path().c_str(),
                                                 GENERIC_READ,
                                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                                 nullptr,
                                                 OPEN_EXISTING,
                                                 FILE_ATTRIBUTE_NORMAL,
                                                 nullptr) };

            if (hFile)
            {
                const auto fileData = _ReadFile(hFile.get()).value();
                jsonFiles.emplace(fileData);
            }
        }
    }
    return jsonFiles;
}

// Method Description:
// - Given a set of json files, uses them to modify existing profiles,
//   create new profiles, and create new colour schemes
// Arguments:
// - stubs: the set of json files
// - source: the location the files came from
void CascadiaSettings::_AddOrModifyProfiles(const std::unordered_set<std::string> files, const winrt::hstring source)
{

Review comment (bug):
What's checking here for failure to open the file? Just `if (hFile)`?

Do we want to check last error and throw it if we can't open it so it could be reported to the user somehow? (Or at least log it?)

Code after:
                _ParseAndLayerFragmentFiles(jsonFiles, ext.Package().Id().FamilyName().c_str());
            }
        }
    }
}

// Method Description:
// - Helper function to apply json stubs in the local app data folder and the global program data folder
// Arguments:
// - The directory to find json files in
// - The set of ignored namespaces
void CascadiaSettings::_ApplyJsonStubsHelper(const std::wstring_view directory, const std::unordered_set<std::wstring>& ignoredNamespaces)
{
    // The json files should be within subdirectories where the subdirectory name is the app name
    for (const auto& fragmentExtFolder : std::filesystem::directory_iterator(directory))
    {
        // We only want the parent folder name as the source (not the full path)
        const auto source = fragmentExtFolder.path().filename().wstring();

        // Only apply the stubs if the parent folder name is not in ignored namespaces
        // (also make sure this is a directory for sanity)
        if (std::filesystem::is_directory(fragmentExtFolder) && ignoredNamespaces.find(source) == ignoredNamespaces.end())
        {
            const auto jsonFiles = _AccumulateJsonFilesInDirectory(fragmentExtFolder.path().c_str());
            _ParseAndLayerFragmentFiles(jsonFiles, winrt::hstring{ source });
        }
    }
}

// Method Description:
// - Finds all the json files within the given directory
// Arguments:
// - directory: the directory to search
// Return Value:
// - A set containing all the found file data
std::unordered_set<std::string> CascadiaSettings::_AccumulateJsonFilesInDirectory(const std::wstring_view directory)
{
    std::unordered_set<std::string> jsonFiles;

    for (const auto& fragmentExt : std::filesystem::directory_iterator(directory))
    {
        if (fragmentExt.path().extension() == jsonExtension)
        {
            wil::unique_hfile hFile{ CreateFileW(fragmentExt.path().c_str(),
                                                 GENERIC_READ,
                                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                                 nullptr,
                                                 OPEN_EXISTING,
                                                 FILE_ATTRIBUTE_NORMAL,
                                                 nullptr) };