Skip to content

Commit 290c7d2

Browse files
committed
⬆️ Bump gcm from v2.6.1 to v2.7.0
# git-ecosystem/git-credential-manager - macospreferences: add class to read macOS app preferences git-ecosystem/git-credential-manager@5f6d32a - macossettings: implement default settings for macOS git-ecosystem/git-credential-manager@b05317f - Return only unique accounts from credential stores (#1369) git-ecosystem/git-credential-manager@4e2a898 - trace2: fix pipe/socket name parsing git-ecosystem/git-credential-manager@d4e2f59 - trace2: use 'fmt' for the formatted message event field git-ecosystem/git-credential-manager@480b32c - Fix: Add flag to search query for SecretService to retrieve all accounts git-ecosystem/git-credential-manager@f6fe9ca # devlooped/oss - Upgrade create-pull-request action to version 8 devlooped/oss@d00364f - Disable warnings for non-packable test projects devlooped/oss@95b338b - Update versioning scheme in Directory.Build.props devlooped/oss@f2400ef - Enable package pruning in Directory.Build.props devlooped/oss@0ff8b7b - Enhance include workflow with OSMF EULA support devlooped/oss@f2050db - Trim whitespace in file content replacement devlooped/oss@e53557f - Fix path pattern for markdown files in workflow devlooped/oss@6a6de05 - Fix error message quotes in includes.yml devlooped/oss@26e8cb7 - Change label from 'docs' to 'dependencies' devlooped/oss@2d1fb4e - Avoid failure on PR creation if osmfeula.txt doesn't exist in repo devlooped/oss@8ff5178 - Update create-pull-request action to version 8 devlooped/oss@0662872 - Ignore sponsorlink sources in formatting devlooped/oss@f571a42 - SponsorLink code should be checked as regular code devlooped/oss@e81ab75 - Set severity of IDE1100 to none devlooped/oss@1ed9afe - Set explicit tab size and eol for code files devlooped/oss@5dba0d0 - Revert EOL change in editorconfig for C# files devlooped/oss@2d0e5a5 - Revert indent size for project files devlooped/oss@a62c459
1 parent 1b9fff1 commit 290c7d2

File tree

14 files changed

+695
-179
lines changed

14 files changed

+695
-179
lines changed

.editorconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ indent_size = 2
3030

3131
# Dotnet code style settings:
3232
[*.{cs,vb}]
33+
tab_width = 4
34+
3335
# Sort using and Import directives with System.* appearing first
3436
dotnet_sort_system_directives_first = true
3537
# Avoid "this." and "Me." if not necessary
@@ -57,6 +59,9 @@ dotnet_style_require_accessibility_modifiers = omit_if_default:error
5759
# IDE0040: Add accessibility modifiers
5860
dotnet_diagnostic.IDE0040.severity = error
5961

62+
# IDE1100: Error reading content of source file 'Project.TargetFrameworkMoniker' (i.e. from ThisAssembly)
63+
dotnet_diagnostic.IDE1100.severity = none
64+
6065
[*.cs]
6166
# Top-level files are definitely OK
6267
csharp_using_directive_placement = outside_namespace:silent

.github/workflows/includes.yml

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ on:
55
branches:
66
- 'main'
77
paths:
8-
- '**.md'
8+
- '**.md'
99
- '!changelog.md'
10+
- 'osmfeula.txt'
1011

1112
jobs:
1213
includes:
@@ -31,14 +32,33 @@ jobs:
3132
- name: +Mᐁ includes
3233
uses: devlooped/actions-includes@v1
3334

35+
- name: 📝 OSMF EULA
36+
shell: pwsh
37+
run: |
38+
$file = "osmfeula.txt"
39+
$props = "src/Directory.Build.props"
40+
if (-not (test-path $file) -or -not (test-path $props)) {
41+
exit 0
42+
}
43+
44+
$product = dotnet msbuild $props -getproperty:Product
45+
if (-not $product) {
46+
write-error 'To use OSMF EULA, ensure the $(Product) property is set in Directory.props'
47+
exit 1
48+
}
49+
50+
((get-content -raw $file) -replace '\$product\$',$product).trim() | set-content $file
51+
3452
- name: ✍ pull request
35-
uses: peter-evans/create-pull-request@v6
53+
uses: peter-evans/create-pull-request@v8
3654
with:
37-
add-paths: '**.md'
55+
add-paths: |
56+
**.md
57+
*.txt
3858
base: main
3959
branch: markdown-includes
4060
delete-branch: true
41-
labels: docs
61+
labels: dependencies
4262
author: ${{ env.BOT_AUTHOR }}
4363
committer: ${{ env.BOT_AUTHOR }}
4464
commit-message: +Mᐁ includes

.netconfig

Lines changed: 158 additions & 140 deletions
Large diffs are not rendered by default.

src/Core/CommandContext.cs

Lines changed: 1 addition & 1 deletion
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/Core/Constants.cs

Lines changed: 1 addition & 0 deletions
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>

src/Core/Interop/Linux/SecretServiceCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ private unsafe IEnumerable<ICredential> Enumerate(string service, string account
6666
secService,
6767
ref schema,
6868
queryAttrs,
69-
SecretSearchFlags.SECRET_SEARCH_UNLOCK,
69+
SecretSearchFlags.SECRET_SEARCH_UNLOCK | SecretSearchFlags.SECRET_SEARCH_ALL,
7070
IntPtr.Zero,
7171
out error);
7272

src/Core/Interop/MacOS/MacOSKeychain.cs

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public IList<string> GetAccounts(string service)
6666
if (typeId == CFArrayGetTypeID())
6767
{
6868
int len = (int)CFArrayGetCount(resultPtr);
69-
// NOTE: removed len from HashSet ctor since it's not supported in NS2.0
7069
var accounts = new HashSet<string>();
7170
for (int i = 0; i < len; i++)
7271
{
@@ -303,35 +302,18 @@ private static string GetStringAttribute(IntPtr dict, IntPtr key)
303302
return null;
304303
}
305304

306-
IntPtr buffer = IntPtr.Zero;
307-
try
305+
if (CFDictionaryGetValueIfPresent(dict, key, out IntPtr value) && value != IntPtr.Zero)
308306
{
309-
if (CFDictionaryGetValueIfPresent(dict, key, out IntPtr value) && value != IntPtr.Zero)
307+
if (CFGetTypeID(value) == CFStringGetTypeID())
310308
{
311-
if (CFGetTypeID(value) == CFStringGetTypeID())
312-
{
313-
int stringLength = (int)CFStringGetLength(value);
314-
int bufferSize = stringLength + 1;
315-
buffer = Marshal.AllocHGlobal(bufferSize);
316-
if (CFStringGetCString(value, buffer, bufferSize, CFStringEncoding.kCFStringEncodingUTF8))
317-
{
318-
return Marshal.PtrToStringAuto(buffer, stringLength);
319-
}
320-
}
321-
322-
if (CFGetTypeID(value) == CFDataGetTypeID())
323-
{
324-
int length = CFDataGetLength(value);
325-
IntPtr ptr = CFDataGetBytePtr(value);
326-
return Marshal.PtrToStringAuto(ptr, length);
327-
}
309+
return CFStringToString(value);
328310
}
329-
}
330-
finally
331-
{
332-
if (buffer != IntPtr.Zero)
311+
312+
if (CFGetTypeID(value) == CFDataGetTypeID())
333313
{
334-
Marshal.FreeHGlobal(buffer);
314+
int length = CFDataGetLength(value);
315+
IntPtr ptr = CFDataGetBytePtr(value);
316+
return Marshal.PtrToStringAuto(ptr, length);
335317
}
336318
}
337319

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using GitCredentialManager.Interop.MacOS.Native;
4+
using static GitCredentialManager.Interop.MacOS.Native.CoreFoundation;
5+
6+
namespace GitCredentialManager.Interop.MacOS;
7+
8+
public class MacOSPreferences
9+
{
10+
private readonly string _appId;
11+
12+
public MacOSPreferences(string appId)
13+
{
14+
EnsureArgument.NotNull(appId, nameof(appId));
15+
16+
_appId = appId;
17+
}
18+
19+
/// <summary>
20+
/// Return a <see cref="string"/> typed value from the app preferences.
21+
/// </summary>
22+
/// <param name="key">Preference name.</param>
23+
/// <exception cref="InvalidOperationException">Thrown if the preference is not a string.</exception>
24+
/// <returns>
25+
/// <see cref="string"/> or null if the preference with the given key does not exist.
26+
/// </returns>
27+
public string GetString(string key)
28+
{
29+
return TryGet(key, CFStringToString, out string value)
30+
? value
31+
: null;
32+
}
33+
34+
/// <summary>
35+
/// Return a <see cref="int"/> typed value from the app preferences.
36+
/// </summary>
37+
/// <param name="key">Preference name.</param>
38+
/// <exception cref="InvalidOperationException">Thrown if the preference is not an integer.</exception>
39+
/// <returns>
40+
/// <see cref="int"/> or null if the preference with the given key does not exist.
41+
/// </returns>
42+
public int? GetInteger(string key)
43+
{
44+
return TryGet(key, CFNumberToInt32, out int value)
45+
? value
46+
: null;
47+
}
48+
49+
/// <summary>
50+
/// Return a <see cref="IDictionary{TKey,TValue}"/> typed value from the app preferences.
51+
/// </summary>
52+
/// <param name="key">Preference name.</param>
53+
/// <exception cref="InvalidOperationException">Thrown if the preference is not a dictionary.</exception>
54+
/// <returns>
55+
/// <see cref="IDictionary{TKey,TValue}"/> or null if the preference with the given key does not exist.
56+
/// </returns>
57+
public IDictionary<string, string> GetDictionary(string key)
58+
{
59+
return TryGet(key, CFDictionaryToDictionary, out IDictionary<string, string> value)
60+
? value
61+
: null;
62+
}
63+
64+
private bool TryGet<T>(string key, Func<IntPtr, T> converter, out T value)
65+
{
66+
IntPtr cfValue = IntPtr.Zero;
67+
IntPtr keyPtr = IntPtr.Zero;
68+
IntPtr appIdPtr = CreateAppIdPtr();
69+
70+
try
71+
{
72+
keyPtr = CFStringCreateWithCString(IntPtr.Zero, key, CFStringEncoding.kCFStringEncodingUTF8);
73+
cfValue = CFPreferencesCopyAppValue(keyPtr, appIdPtr);
74+
75+
if (cfValue == IntPtr.Zero)
76+
{
77+
value = default;
78+
return false;
79+
}
80+
81+
value = converter(cfValue);
82+
return true;
83+
}
84+
finally
85+
{
86+
if (cfValue != IntPtr.Zero) CFRelease(cfValue);
87+
if (keyPtr != IntPtr.Zero) CFRelease(keyPtr);
88+
if (appIdPtr != IntPtr.Zero) CFRelease(appIdPtr);
89+
}
90+
}
91+
92+
private IntPtr CreateAppIdPtr()
93+
{
94+
return CFStringCreateWithCString(IntPtr.Zero, _appId, CFStringEncoding.kCFStringEncodingUTF8);
95+
}
96+
}
Lines changed: 67 additions & 0 deletions
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)