Browse Source

Handle being unable to read or update NuGet.Config.

pull/622/head
Matt Ward 12 years ago
parent
commit
56ef4ff293
  1. 1
      src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj
  2. 8
      src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeSettings.cs
  3. 53
      src/AddIns/Misc/PackageManagement/Project/Src/MessageServiceExtensions.cs
  4. 7
      src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementOptionsView.xaml.cs
  5. 13
      src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs
  6. 25
      src/AddIns/Misc/PackageManagement/Project/Src/RegisteredPackageSourceSettings.cs
  7. 8
      src/AddIns/Misc/PackageManagement/Project/Src/RegisteredPackageSourcesView.xaml.cs
  8. 6
      src/AddIns/Misc/PackageManagement/Project/Src/SettingsProvider.cs
  9. 1
      src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj
  10. 46
      src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeReadOnlySettings.cs
  11. 40
      src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsTests.cs
  12. 14
      src/AddIns/Misc/PackageManagement/Test/Src/SettingsProviderTests.cs

1
src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj

@ -224,6 +224,7 @@
<Compile Include="Src\IThreadSafePackageManagementEvents.cs" /> <Compile Include="Src\IThreadSafePackageManagementEvents.cs" />
<Compile Include="Src\ManagePackagesUserPrompts.cs" /> <Compile Include="Src\ManagePackagesUserPrompts.cs" />
<Compile Include="Src\ManagePackagesViewTitle.cs" /> <Compile Include="Src\ManagePackagesViewTitle.cs" />
<Compile Include="Src\MessageServiceExtensions.cs" />
<Compile Include="Src\MSBuildBasedProjectExtensions.cs" /> <Compile Include="Src\MSBuildBasedProjectExtensions.cs" />
<Compile Include="Src\IPackageFromRepositoryExtensions.cs" /> <Compile Include="Src\IPackageFromRepositoryExtensions.cs" />
<Compile Include="Src\NoPackageSourcesConfiguredException.cs" /> <Compile Include="Src\NoPackageSourcesConfiguredException.cs" />

8
src/AddIns/Misc/PackageManagement/Project/Src/Design/FakeSettings.cs

@ -100,14 +100,14 @@ namespace ICSharpCode.PackageManagement.Design
return SavedSectionValueLists[RegisteredPackageSourceSettings.PackageSourcesSectionName]; return SavedSectionValueLists[RegisteredPackageSourceSettings.PackageSourcesSectionName];
} }
public bool DeleteValue(string section, string key) public virtual bool DeleteValue(string section, string key)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public List<string> SectionsDeleted = new List<string>(); public List<string> SectionsDeleted = new List<string>();
public bool DeleteSection(string section) public virtual bool DeleteSection(string section)
{ {
SectionsDeleted.Add(section); SectionsDeleted.Add(section);
return true; return true;
@ -162,7 +162,7 @@ namespace ICSharpCode.PackageManagement.Design
return new List<KeyValuePair<string, string>>(); return new List<KeyValuePair<string, string>>();
} }
public void SetNestedValues(string section, string key, IList<KeyValuePair<string, string>> values) public virtual void SetNestedValues(string section, string key, IList<KeyValuePair<string, string>> values)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -184,7 +184,7 @@ namespace ICSharpCode.PackageManagement.Design
} }
} }
public void SetPackageRestoreSetting(bool enabled) public virtual void SetPackageRestoreSetting(bool enabled)
{ {
var items = new List<KeyValuePair<string, string>>(); var items = new List<KeyValuePair<string, string>>();
items.Add(new KeyValuePair<string, string>("enabled", enabled.ToString())); items.Add(new KeyValuePair<string, string>("enabled", enabled.ToString()));

53
src/AddIns/Misc/PackageManagement/Project/Src/MessageServiceExtensions.cs

@ -0,0 +1,53 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.IO;
using ICSharpCode.Core;
namespace ICSharpCode.PackageManagement
{
public static class MessageServiceExtensions
{
public static void ShowNuGetConfigFileSaveError(string message)
{
MessageService.ShowError(
String.Format("{0}{1}{1}{2}",
message,
Environment.NewLine,
GetSaveNuGetConfigFileErrorMessage()));
}
/// <summary>
/// Returns a non-Windows specific error message instead of the one NuGet returns.
///
/// NuGet returns a Windows specific error:
///
/// "DeleteSection" cannot be called on a NullSettings. This may be caused on account of
/// insufficient permissions to read or write to "%AppData%\NuGet\NuGet.config".
/// </summary>
static string GetSaveNuGetConfigFileErrorMessage()
{
string path = Path.Combine (
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"NuGet",
"NuGet.config");
return String.Format("Unable to read or write to \"{0}\".", path);
}
}
}

7
src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementOptionsView.xaml.cs

@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.PackageManagement namespace ICSharpCode.PackageManagement
@ -30,9 +31,15 @@ namespace ICSharpCode.PackageManagement
public override bool SaveOptions() public override bool SaveOptions()
{ {
try {
var viewModel = DataContext as PackageManagementOptionsViewModel; var viewModel = DataContext as PackageManagementOptionsViewModel;
viewModel.SaveOptions(); viewModel.SaveOptions();
return true; return true;
} catch (Exception ex) {
LoggingService.Error("Unable to save NuGet.config changes", ex);
MessageServiceExtensions.ShowNuGetConfigFileSaveError("Unable to save package management options.");
}
return false;
} }
} }
} }

13
src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs

@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using ICSharpCode.Core;
using ICSharpCode.PackageManagement.Scripting; using ICSharpCode.PackageManagement.Scripting;
using NuGet; using NuGet;
@ -61,13 +62,23 @@ namespace ICSharpCode.PackageManagement
static void InitializeCredentialProvider() static void InitializeCredentialProvider()
{ {
ISettings settings = Settings.LoadDefaultSettings(null, null, null); ISettings settings = LoadSettings();
var packageSourceProvider = new PackageSourceProvider(settings); var packageSourceProvider = new PackageSourceProvider(settings);
var credentialProvider = new SettingsCredentialProvider(new SharpDevelopCredentialProvider(), packageSourceProvider); var credentialProvider = new SettingsCredentialProvider(new SharpDevelopCredentialProvider(), packageSourceProvider);
HttpClient.DefaultCredentialProvider = credentialProvider; HttpClient.DefaultCredentialProvider = credentialProvider;
} }
static ISettings LoadSettings ()
{
try {
return Settings.LoadDefaultSettings(null, null, null);
} catch (Exception ex) {
LoggingService.Error("Unable to load NuGet.Config.", ex);
}
return NullSettings.Instance;
}
public static PackageManagementOptions Options { public static PackageManagementOptions Options {
get { return options; } get { return options; }
} }

25
src/AddIns/Misc/PackageManagement/Project/Src/RegisteredPackageSourceSettings.cs

@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using NuGet; using NuGet;
@ -82,12 +83,26 @@ namespace ICSharpCode.PackageManagement
public RegisteredPackageSources PackageSources { public RegisteredPackageSources PackageSources {
get { get {
if (packageSources == null) { if (packageSources == null) {
ReadPackageSources(); TryReadPackageSources();
} }
return packageSources; return packageSources;
} }
} }
void TryReadPackageSources()
{
try {
ReadPackageSources();
} catch (Exception ex) {
LoggingService.Warn("Unable to read NuGet.config file.", ex);
// Fallback to using the default package source only (nuget.org)
// and treat NuGet.config as read-only.
packageSourceProvider = CreatePackageSourceProvider(NullSettings.Instance);
ReadPackageSources();
}
}
void ReadPackageSources() void ReadPackageSources()
{ {
IEnumerable<PackageSource> savedPackageSources = packageSourceProvider.LoadPackageSources(); IEnumerable<PackageSource> savedPackageSources = packageSourceProvider.LoadPackageSources();
@ -119,6 +134,12 @@ namespace ICSharpCode.PackageManagement
} }
set { set {
activePackageSource = value; activePackageSource = value;
if (settings is NullSettings) {
// NuGet failed to load settings so do not try to update them since this will fail.
return;
}
if (activePackageSource == null) { if (activePackageSource == null) {
RemoveActivePackageSourceSetting(); RemoveActivePackageSourceSetting();
} else { } else {
@ -148,7 +169,7 @@ namespace ICSharpCode.PackageManagement
void SettingsChanged(object sender, EventArgs e) void SettingsChanged(object sender, EventArgs e)
{ {
settings = settingsProvider.LoadSettings(); settings = settingsProvider.LoadSettings();
packageSourceProvider = new PackageSourceProvider(settings); packageSourceProvider = CreatePackageSourceProvider(settings);
ReadActivePackageSource(); ReadActivePackageSource();
ResetPackageSources(); ResetPackageSources();
} }

8
src/AddIns/Misc/PackageManagement/Project/Src/RegisteredPackageSourcesView.xaml.cs

@ -17,6 +17,8 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.PackageManagement namespace ICSharpCode.PackageManagement
@ -46,8 +48,14 @@ namespace ICSharpCode.PackageManagement
public override bool SaveOptions() public override bool SaveOptions()
{ {
try {
ViewModel.Save(); ViewModel.Save();
return true; return true;
} catch (Exception ex) {
LoggingService.Error("Unable to save NuGet.config changes", ex);
MessageServiceExtensions.ShowNuGetConfigFileSaveError("Unable to save package source changes.");
}
return false;
} }
} }
} }

6
src/AddIns/Misc/PackageManagement/Project/Src/SettingsProvider.cs

@ -3,6 +3,7 @@
using System; using System;
using System.IO; using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using NuGet; using NuGet;
@ -38,7 +39,12 @@ namespace ICSharpCode.PackageManagement
public ISettings LoadSettings() public ISettings LoadSettings()
{ {
try {
return LoadSettings(GetSolutionDirectory()); return LoadSettings(GetSolutionDirectory());
} catch (Exception ex) {
LoggingService.Error("Unable to load NuGet.Config file.", ex);
}
return NullSettings.Instance;
} }
string GetSolutionDirectory() string GetSolutionDirectory()

1
src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj

@ -112,6 +112,7 @@
<Compile Include="Src\Helpers\FakeCodeGenerator.cs" /> <Compile Include="Src\Helpers\FakeCodeGenerator.cs" />
<Compile Include="Src\Helpers\FakeOperationAwarePackageRepository.cs" /> <Compile Include="Src\Helpers\FakeOperationAwarePackageRepository.cs" />
<Compile Include="Src\Helpers\FakePackageRepositoryWithConstraintProvider.cs" /> <Compile Include="Src\Helpers\FakePackageRepositoryWithConstraintProvider.cs" />
<Compile Include="Src\Helpers\FakeReadOnlySettings.cs" />
<Compile Include="Src\Helpers\FakeSelectProjectsService.cs" /> <Compile Include="Src\Helpers\FakeSelectProjectsService.cs" />
<Compile Include="Src\Helpers\FakeServiceBasedRepository.cs" /> <Compile Include="Src\Helpers\FakeServiceBasedRepository.cs" />
<Compile Include="Src\Helpers\FakeSolutionPackageRepositoryFactory.cs" /> <Compile Include="Src\Helpers\FakeSolutionPackageRepositoryFactory.cs" />

46
src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeReadOnlySettings.cs

@ -0,0 +1,46 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using ICSharpCode.PackageManagement.Design;
namespace PackageManagement.Tests.Helpers
{
public class FakeReadOnlySettings : FakeSettings
{
public override bool DeleteSection(string section)
{
throw new ApplicationException("DeleteSection called");
}
public override bool DeleteValue(string section, string key)
{
throw new ApplicationException("DeleteValue called");
}
public override void SetNestedValues(string section, string key, System.Collections.Generic.IList<System.Collections.Generic.KeyValuePair<string, string>> values)
{
throw new ApplicationException("SetNestedValues called");
}
public override void SetPackageRestoreSetting(bool enabled)
{
throw new ApplicationException("SetPackageRestoreSetting called");
}
}
}

40
src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsTests.cs

@ -39,6 +39,13 @@ namespace PackageManagement.Tests
SettingsProvider settingsProvider; SettingsProvider settingsProvider;
FakePackageManagementProjectService projectService; FakePackageManagementProjectService projectService;
[TearDown]
public void TearDown()
{
// This resets SettingsProvider.LoadDefaultSettings.
TestablePackageManagementOptions.CreateSettingsProvider(fakeSettings, projectService);
}
void CreateOptions() void CreateOptions()
{ {
CreateProperties(); CreateProperties();
@ -69,6 +76,12 @@ namespace PackageManagement.Tests
options = new PackageManagementOptions(properties, settingsProvider); options = new PackageManagementOptions(properties, settingsProvider);
} }
void CreateOptions(Properties properties, ISettingsProvider provider)
{
CreateSettings();
options = new PackageManagementOptions(properties, provider);
}
void CreateSettingsProvider(FakeSettings fakeSettings) void CreateSettingsProvider(FakeSettings fakeSettings)
{ {
projectService = new FakePackageManagementProjectService(); projectService = new FakePackageManagementProjectService();
@ -559,5 +572,32 @@ namespace PackageManagement.Tests
Assert.AreEqual(expectedInitialSources, actualInitialPackageSources); Assert.AreEqual(expectedInitialSources, actualInitialPackageSources);
Assert.AreEqual(new PackageSource[] { expectedActivePackageSource }, options.PackageSources); Assert.AreEqual(new PackageSource[] { expectedActivePackageSource }, options.PackageSources);
} }
[Test]
public void PackageSources_ReadOnlyNuGetConfigFile_DoesNotThrowException()
{
var settings = new FakeReadOnlySettings();
CreateOptions(settings);
int count = 0;
Assert.DoesNotThrow(() => count = options.PackageSources.Count);
Assert.AreEqual(1, count);
Assert.AreEqual(options.PackageSources[0], new PackageSource("https://www.nuget.org/api/v2/", "nuget.org"));
}
[Test]
public void PackageSources_UpdateActivePackageSourceWhenNuGetConfigAccessIsUnauthorized_DoesNotThrowException()
{
CreateProperties();
fakeSettings = new FakeReadOnlySettings();
CreateSettingsProvider(fakeSettings);
SettingsProvider.LoadDefaultSettings = (fileSystem, configFile, machineSettings) => {
throw new UnauthorizedAccessException();
};
CreateOptions(properties, settingsProvider);
var packageSource = new PackageSource("http://test.com");
Assert.DoesNotThrow(() => options.ActivePackageSource = packageSource);
}
} }
} }

14
src/AddIns/Misc/PackageManagement/Test/Src/SettingsProviderTests.cs

@ -76,5 +76,19 @@ namespace PackageManagement.Tests
Assert.AreEqual(@"d:\projects\MyProject\.nuget", fileSystemUsedToLoadSettings.Root); Assert.AreEqual(@"d:\projects\MyProject\.nuget", fileSystemUsedToLoadSettings.Root);
Assert.AreEqual(fakeSettings, settings); Assert.AreEqual(fakeSettings, settings);
} }
[Test]
public void LoadSettings_NuGetSettingsThrowsUnauthorizedAccessException_ExceptionHandledAndSettingsNullObjectReturned()
{
fileSystemUsedToLoadSettings = new FakeFileSystem();
configFileUsedToLoadSettings = "configFile";
SettingsProvider.LoadDefaultSettings = (fileSystem, configFile, machineSettings) => {
throw new UnauthorizedAccessException();
};
ISettings settings = settingsProvider.LoadSettings();
Assert.IsInstanceOf<NullSettings>(settings);
}
} }
} }

Loading…
Cancel
Save