Make InvalidRepoException exit normally

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
This commit is contained in:
Derrick Stolee 2020-02-20 11:29:48 -05:00
Родитель 41c3240638
Коммит 24d56dbd35
9 изменённых файлов: 43 добавлений и 31 удалений

Просмотреть файл

@ -36,18 +36,18 @@ namespace Scalar.Common
GitProcess.ConfigResult originResult = gitProcess.GetOriginUrl();
if (!originResult.TryParseAsString(out string originUrl, out string error))
{
throw new InvalidRepoException("Could not get origin url. git error: " + error);
throw new InvalidRepoException(this.WorkingDirectoryRoot, "Could not get origin url. git error: " + error);
}
if (originUrl == null)
{
throw new InvalidRepoException("Could not get origin url. remote 'origin' is not configured for this repo.'");
throw new InvalidRepoException(this.WorkingDirectoryRoot, "Could not get origin url. remote 'origin' is not configured for this repo.'");
}
this.RepoUrl = originUrl.Trim();
}
this.Authentication = authentication ?? new GitAuthentication(gitProcess, this.RepoUrl);
this.Authentication = authentication ?? new GitAuthentication(gitProcess, this.RepoUrl, this.WorkingDirectoryRoot);
}
public string EnlistmentRoot { get; }

Просмотреть файл

@ -25,14 +25,14 @@ namespace Scalar.Common.Git
private bool isInitialized;
public GitAuthentication(GitProcess git, string repoUrl)
public GitAuthentication(GitProcess git, string repoUrl, string repoPath)
{
this.credentialStore = git;
this.repoUrl = repoUrl;
if (git.TryGetConfigUrlMatch("http", this.repoUrl, out Dictionary<string, GitConfigSetting> configSettings))
{
this.GitSsl = new GitSsl(configSettings);
this.GitSsl = new GitSsl(repoPath, configSettings);
}
}

Просмотреть файл

@ -1,13 +1,12 @@
using Scalar.Common.FileSystem;
using Scalar.Common.Tracing;
using Scalar.Common.X509Certificates;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using Scalar.Common.FileSystem;
using Scalar.Common.Tracing;
using Scalar.Common.X509Certificates;
namespace Scalar.Common.Git
{
@ -20,6 +19,7 @@ namespace Scalar.Common.Git
private readonly PhysicalFileSystem fileSystem;
public GitSsl(
string repoPath,
IDictionary<string, GitConfigSetting> configSettings,
Func<SystemCertificateStore> createCertificateStore = null,
CertificateVerifier certificateVerifier = null,
@ -32,9 +32,9 @@ namespace Scalar.Common.Git
this.certificatePathOrSubjectCommonName = sslCerts.Values.Last();
}
this.isCertificatePasswordProtected = SetBoolSettingOrThrow(configSettings, GitConfigSetting.HttpSslCertPasswordProtected, this.isCertificatePasswordProtected);
this.isCertificatePasswordProtected = SetBoolSettingOrThrow(repoPath, configSettings, GitConfigSetting.HttpSslCertPasswordProtected, this.isCertificatePasswordProtected);
this.ShouldVerify = SetBoolSettingOrThrow(configSettings, GitConfigSetting.HttpSslVerify, this.ShouldVerify);
this.ShouldVerify = SetBoolSettingOrThrow(repoPath, configSettings, GitConfigSetting.HttpSslVerify, this.ShouldVerify);
}
}
@ -87,7 +87,7 @@ namespace Scalar.Common.Git
return result;
}
private static bool SetBoolSettingOrThrow(IDictionary<string, GitConfigSetting> configSettings, string settingName, bool currentValue)
private static bool SetBoolSettingOrThrow(string repoPath, IDictionary<string, GitConfigSetting> configSettings, string settingName, bool currentValue)
{
if (configSettings.TryGetValue(settingName, out GitConfigSetting settingValues))
{
@ -97,7 +97,7 @@ namespace Scalar.Common.Git
}
catch (FormatException)
{
throw new InvalidRepoException($"{settingName} git setting did not have a bool-parsable value. Found: {string.Join(" ", settingValues.Values)}");
throw new InvalidRepoException(repoPath, $"{settingName} git setting did not have a bool-parsable value. Found: {string.Join(" ", settingValues.Values)}");
}
}

Просмотреть файл

@ -32,7 +32,7 @@ namespace Scalar.Common.Http
// TODO 1057500: Remove support for encoded-repo-url cache config setting
return
GetValueFromConfig(git, ScalarConstants.GitConfig.CacheServer, localOnly: true)
GetValueFromConfig(enlistment.WorkingDirectoryRoot, git, ScalarConstants.GitConfig.CacheServer, localOnly: true)
?? enlistment.RepoUrl;
}
@ -128,7 +128,7 @@ namespace Scalar.Common.Http
return result.ExitCodeIsSuccess;
}
private static string GetValueFromConfig(GitProcess git, string configName, bool localOnly)
private static string GetValueFromConfig(string repoPath, GitProcess git, string configName, bool localOnly)
{
GitProcess.ConfigResult result =
localOnly
@ -137,7 +137,7 @@ namespace Scalar.Common.Http
if (!result.TryParseAsString(out string value, out string error))
{
throw new InvalidRepoException(error);
throw new InvalidRepoException(repoPath, error);
}
return value;

Просмотреть файл

@ -4,9 +4,12 @@ namespace Scalar.Common
{
public class InvalidRepoException : Exception
{
public InvalidRepoException(string message)
public string RepoPath { get; }
public InvalidRepoException(string repoPath, string message)
: base(message)
{
this.RepoPath = repoPath;
}
}
}

Просмотреть файл

@ -69,7 +69,7 @@ namespace Scalar.Common
if (!TryGetScalarEnlistmentRoot(directory, out enlistmentRoot, out workingDirectory))
{
throw new InvalidRepoException($"Could not get enlistment root.");
throw new InvalidRepoException(directory, $"Could not get enlistment root.");
}
if (createWithoutRepoURL)
@ -80,7 +80,7 @@ namespace Scalar.Common
return new ScalarEnlistment(enlistmentRoot, workingDirectory, null, gitBinRoot, authentication);
}
throw new InvalidRepoException($"Directory '{directory}' does not exist");
throw new InvalidRepoException(directory, $"Directory '{directory}' does not exist");
}
public static string GetNewScalarLogFileName(

Просмотреть файл

@ -55,7 +55,7 @@ namespace Scalar.UnitTests.Common.Git
IDictionary<string, GitConfigSetting> gitConfig = new Dictionary<string, GitConfigSetting>();
gitConfig.Add(setting, new GitConfigSetting(setting, "true", "this is true"));
Assert.Throws<InvalidRepoException>(() => new GitSsl(gitConfig));
Assert.Throws<InvalidRepoException>(() => new GitSsl(string.Empty, gitConfig));
}
[TestCaseSource(typeof(GitSslTests), nameof(GitSslTests.BoolGitSettings))]
@ -64,13 +64,13 @@ namespace Scalar.UnitTests.Common.Git
IDictionary<string, GitConfigSetting> gitConfig = new Dictionary<string, GitConfigSetting>();
gitConfig.Add(setting, new GitConfigSetting(setting, "this is true", "true"));
Assert.DoesNotThrow(() => new GitSsl(gitConfig));
Assert.DoesNotThrow(() => new GitSsl(string.Empty, gitConfig));
}
[TestCase]
public void GetCertificateShouldReturnNullWhenCertificateCommonNameSettingIsEmpty()
{
GitSsl sut = new GitSsl(new Dictionary<string, GitConfigSetting>());
GitSsl sut = new GitSsl(string.Empty, new Dictionary<string, GitConfigSetting>());
X509Certificate2 result = sut.GetCertificate(this.tracer, this.gitProcess);
result.ShouldBeNull();
}
@ -82,7 +82,7 @@ namespace Scalar.UnitTests.Common.Git
this.SetupCertificateFile(certificate, CertificatePassword);
this.SetupGitCertificatePassword();
this.MakeCertificateValid(certificate);
GitSsl gitSsl = new GitSsl(GetGitConfig(), () => this.certificateStoreMock.Object, this.certificateVerifierMock.Object, this.fileSystem);
GitSsl gitSsl = new GitSsl(string.Empty, GetGitConfig(), () => this.certificateStoreMock.Object, this.certificateVerifierMock.Object, this.fileSystem);
X509Certificate2 result = gitSsl.GetCertificate(this.tracer, this.gitProcess);
@ -97,6 +97,7 @@ namespace Scalar.UnitTests.Common.Git
this.SetupCertificateFile(certificate);
this.MakeCertificateValid(certificate);
GitSsl gitSsl = new GitSsl(
string.Empty,
GetGitConfig(
new GitConfigSetting(GitConfigSetting.HttpSslCertPasswordProtected, "false")),
() => this.certificateStoreMock.Object,
@ -116,6 +117,7 @@ namespace Scalar.UnitTests.Common.Git
this.SetupCertificateFile(certificate);
this.MakeCertificateValid(certificate, false);
GitSsl gitSsl = new GitSsl(
string.Empty,
GetGitConfig(
new GitConfigSetting(GitConfigSetting.HttpSslCertPasswordProtected, "false")),
() => this.certificateStoreMock.Object,
@ -134,6 +136,7 @@ namespace Scalar.UnitTests.Common.Git
this.SetupCertificateFile(certificate);
this.MakeCertificateValid(certificate, false);
GitSsl gitSsl = new GitSsl(
string.Empty,
GetGitConfig(
new GitConfigSetting(GitConfigSetting.HttpSslCertPasswordProtected, "false"),
new GitConfigSetting(GitConfigSetting.HttpSslVerify, "false")),
@ -153,6 +156,7 @@ namespace Scalar.UnitTests.Common.Git
X509Certificate2 certificate = this.MakeCertificateValid(GenerateTestCertificate());
this.SetupGitCertificatePassword();
GitSsl gitSsl = new GitSsl(
string.Empty,
GetGitConfig(),
() => this.certificateStoreMock.Object,
this.certificateVerifierMock.Object,
@ -179,6 +183,7 @@ namespace Scalar.UnitTests.Common.Git
{
this.SetupGitCertificatePassword();
GitSsl gitSsl = new GitSsl(
string.Empty,
GetGitConfig(),
() => this.certificateStoreMock.Object,
this.certificateVerifierMock.Object,

Просмотреть файл

@ -27,7 +27,7 @@ namespace Scalar.UnitTests.Git
MockTracer tracer = new MockTracer();
MockGitProcess gitProcess = this.GetGitProcess();
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl");
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl", "fake path");
dut.TryInitializeAndRequireAuth(tracer, out _);
string authString;
@ -54,7 +54,7 @@ namespace Scalar.UnitTests.Git
MockTracer tracer = new MockTracer();
MockGitProcess gitProcess = this.GetGitProcess();
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl");
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl", "fake path");
dut.TryInitializeAndRequireAuth(tracer, out _);
string authString;
@ -78,7 +78,7 @@ namespace Scalar.UnitTests.Git
MockTracer tracer = new MockTracer();
MockGitProcess gitProcess = this.GetGitProcess();
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl");
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl", "fake path");
dut.TryInitializeAndRequireAuth(tracer, out _);
string authString;
@ -105,7 +105,7 @@ namespace Scalar.UnitTests.Git
MockTracer tracer = new MockTracer();
MockGitProcess gitProcess = this.GetGitProcess();
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl");
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl", "fake path");
dut.TryInitializeAndRequireAuth(tracer, out _);
string authString;
@ -132,7 +132,7 @@ namespace Scalar.UnitTests.Git
MockTracer tracer = new MockTracer();
MockGitProcess gitProcess = this.GetGitProcess();
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl");
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl", "fake path");
dut.TryInitializeAndRequireAuth(tracer, out _);
string thread1Auth;
@ -168,7 +168,7 @@ namespace Scalar.UnitTests.Git
MockTracer tracer = new MockTracer();
MockGitProcess gitProcess = this.GetGitProcess();
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl");
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl", "fake path");
dut.TryInitializeAndRequireAuth(tracer, out _);
string thread1Auth;
@ -205,7 +205,7 @@ namespace Scalar.UnitTests.Git
MockTracer tracer = new MockTracer();
MockGitProcess gitProcess = this.GetGitProcess();
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl");
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl", "fake path");
dut.TryInitializeAndRequireAuth(tracer, out _);
string authString;
@ -228,7 +228,7 @@ namespace Scalar.UnitTests.Git
MockTracer tracer = new MockTracer();
MockGitProcess gitProcess = this.GetGitProcess();
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl");
GitAuthentication dut = new GitAuthentication(gitProcess, "mock://repoUrl", "fake path");
dut.TryInitializeAndRequireAuth(tracer, out _);
// Get and store an initial value that will be cached

Просмотреть файл

@ -107,6 +107,10 @@ namespace Scalar.CommandLine
{
verb.Execute();
}
catch (InvalidRepoException ire)
{
this.ReportErrorAndExit($"Invalid repository: {ire.Message}");
}
catch (VerbAbortedException)
{
}