Skip to content

Commit b05317f

Browse files
committed
macossettings: implement default settings for macOS
1 parent 5f6d32a commit b05317f

File tree

4 files changed

+101
-2
lines changed

4 files changed

+101
-2
lines changed

docs/enterprise-config.md

+32-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,38 @@ those of the [Git configuration][config] settings.
5555
The type of each registry key can be either `REG_SZ` (string) or `REG_DWORD`
5656
(integer).
5757

58-
## macOS/Linux
58+
## macOS
59+
60+
Default settings values come from macOS's preferences system. Configuration
61+
profiles can be deployed to devices using a compatible Mobile Device Management
62+
(MDM) solution.
63+
64+
Configuration for Git Credential Manager must take the form of a dictionary, set
65+
for the domain `git-credential-manager` under the key `configuration`. For
66+
example:
67+
68+
```shell
69+
defaults write git-credential-manager configuration -dict-add <key> <value>
70+
```
71+
72+
..where `<key>` is the name of the settings from the [Git configuration][config]
73+
reference, and `<value>` is the desired value.
74+
75+
All values in the `configuration` dictionary must be strings. For boolean values
76+
use `true` or `false`, and for integer values use the number in string form.
77+
78+
To read the current configuration:
79+
80+
```console
81+
$ defaults read git-credential-manager configuration
82+
{
83+
<key1> = <value1>;
84+
...
85+
<keyN> = <valueN>;
86+
}
87+
```
88+
89+
## Linux
5990

6091
Default configuration setting stores has not been implemented.
6192

src/shared/Core/CommandContext.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public CommandContext()
131131
gitPath,
132132
FileSystem.GetCurrentDirectory()
133133
);
134-
Settings = new Settings(Environment, Git);
134+
Settings = new MacOSSettings(Environment, Git, Trace);
135135
}
136136
else if (PlatformUtils.IsLinux())
137137
{

src/shared/Core/Constants.cs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public static class Constants
1616

1717
public const string GcmDataDirectoryName = ".gcm";
1818

19+
public const string MacOSBundleId = "git-credential-manager";
1920
public static readonly Guid DevBoxPartnerId = new("e3171dd9-9a5f-e5be-b36c-cc7c4f3f3bcf");
2021

2122
/// <summary>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace GitCredentialManager.Interop.MacOS
5+
{
6+
/// <summary>
7+
/// Reads settings from Git configuration, environment variables, and defaults from the system.
8+
/// </summary>
9+
public class MacOSSettings : Settings
10+
{
11+
private readonly ITrace _trace;
12+
13+
public MacOSSettings(IEnvironment environment, IGit git, ITrace trace)
14+
: base(environment, git)
15+
{
16+
EnsureArgument.NotNull(trace, nameof(trace));
17+
_trace = trace;
18+
19+
PlatformUtils.EnsureMacOS();
20+
}
21+
22+
protected override bool TryGetExternalDefault(string section, string scope, string property, out string value)
23+
{
24+
value = null;
25+
26+
try
27+
{
28+
// Check for app default preferences for our bundle ID.
29+
// Defaults can be deployed system administrators via device management profiles.
30+
var prefs = new MacOSPreferences(Constants.MacOSBundleId);
31+
IDictionary<string, string> dict = prefs.GetDictionary("configuration");
32+
33+
if (dict is null)
34+
{
35+
// No configuration key exists
36+
return false;
37+
}
38+
39+
// Wrap the raw dictionary in one configured with the Git configuration key comparer.
40+
// This means we can use the same key comparison rules as Git in our configuration plist dict,
41+
// That is, sections and names are insensitive to case, but the scope is case-sensitive.
42+
var config = new Dictionary<string, string>(dict, GitConfigurationKeyComparer.Instance);
43+
44+
string name = string.IsNullOrWhiteSpace(scope)
45+
? $"{section}.{property}"
46+
: $"{section}.{scope}.{property}";
47+
48+
if (!config.TryGetValue(name, out value))
49+
{
50+
// No property exists
51+
return false;
52+
}
53+
54+
_trace.WriteLine($"Default setting found in app preferences: {name}={value}");
55+
return true;
56+
}
57+
catch (Exception ex)
58+
{
59+
// Reading defaults is not critical to the operation of the application
60+
// so we can ignore any errors and just log the failure.
61+
_trace.WriteLine("Failed to read default setting from app preferences.");
62+
_trace.WriteException(ex);
63+
return false;
64+
}
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)