From 013f2a1aaa14b8313aea4bef004b7b9f0ce7c0dc Mon Sep 17 00:00:00 2001 From: Mark Siedle Date: Wed, 30 Mar 2016 13:31:07 +1000 Subject: [PATCH 1/5] Fix to allow custom expressions in Nuget feeds for projects --- NuGet.config | 6 ++- source/Octopus.Cli/Commands/ImportCommand.cs | 3 +- .../Octopus.Cli/Exporters/ProjectExporter.cs | 11 ++++-- .../Octopus.Cli/Importers/ProjectImporter.cs | 14 ++++--- source/Octopus.Cli/Octopus.Cli.csproj | 1 + .../FeedResourceCustomExpressionHelper.cs | 39 +++++++++++++++++++ 6 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs diff --git a/NuGet.config b/NuGet.config index b2bee8970..be0cb23db 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,4 +1,4 @@ - + @@ -11,7 +11,11 @@ + + + + diff --git a/source/Octopus.Cli/Commands/ImportCommand.cs b/source/Octopus.Cli/Commands/ImportCommand.cs index 7f949da6e..c2bdbc6ca 100644 --- a/source/Octopus.Cli/Commands/ImportCommand.cs +++ b/source/Octopus.Cli/Commands/ImportCommand.cs @@ -1,5 +1,4 @@ -using System; -using log4net; +using log4net; using Octopus.Cli.Importers; using Octopus.Cli.Infrastructure; using Octopus.Cli.Util; diff --git a/source/Octopus.Cli/Exporters/ProjectExporter.cs b/source/Octopus.Cli/Exporters/ProjectExporter.cs index abe615260..a38f165fe 100644 --- a/source/Octopus.Cli/Exporters/ProjectExporter.cs +++ b/source/Octopus.Cli/Exporters/ProjectExporter.cs @@ -29,6 +29,7 @@ protected override void Export(Dictionary parameters) { throw new CommandException("Please specify the name of the project to export using the paramater: --name=XYZ"); } + var projectName = parameters["Name"]; Log.Debug("Finding project: " + projectName); @@ -82,10 +83,15 @@ protected override void Export(Dictionary parameters) PropertyValueResource nugetFeedId; if (action.Properties.TryGetValue("Octopus.Action.Package.NuGetFeedId", out nugetFeedId)) { - Log.Debug("Finding NuGet feed for step " + step.Name); - var feed = Repository.Feeds.Get(nugetFeedId.Value); + FeedResource feed = null; + if (FeedResourceCustomExpressionHelper.IsValidRepositoryId(nugetFeedId.Value)) + feed = Repository.Feeds.Get(nugetFeedId.Value); + else + feed = FeedResourceCustomExpressionHelper.FeedResourceWithId(nugetFeedId.Value); + if (feed == null) throw new CouldNotFindException("NuGet feed for step", step.Name); + if (nugetFeeds.All(f => f.Id != nugetFeedId.Value)) { nugetFeeds.Add(new ReferenceDataItem(feed.Id, feed.Name)); @@ -123,7 +129,6 @@ protected override void Export(Dictionary parameters) { throw new CouldNotFindException("library variable set with Id", libraryVariableSetId); } - libraryVariableSets.Add(new ReferenceDataItem(libraryVariableSet.Id, libraryVariableSet.Name)); } diff --git a/source/Octopus.Cli/Importers/ProjectImporter.cs b/source/Octopus.Cli/Importers/ProjectImporter.cs index 8c2f43c78..38ff2fcdb 100644 --- a/source/Octopus.Cli/Importers/ProjectImporter.cs +++ b/source/Octopus.Cli/Importers/ProjectImporter.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Security.Permissions; using log4net; using Octopus.Cli.Commands; using Octopus.Cli.Extensions; @@ -37,8 +36,7 @@ class ValidatedImportSettings : BaseValidatedImportSettings public IDictionary Templates { get; set; } public VariableSetResource VariableSet { get; set; } public IEnumerable Channels { get; set; } - public IDictionary ChannelLifecycles { get; set; } - + public IDictionary ChannelLifecycles { get; set; } } public ProjectImporter(IOctopusRepository repository, IOctopusFileSystem fileSystem, ILog log) @@ -59,6 +57,7 @@ protected override bool Validate(Dictionary paramDictionary) { throw new CommandException("Unable to find a lifecycle to assign to this project."); } + Log.DebugFormat("Found lifecycle '{0}'", existingLifecycle.Name); project.LifecycleId = existingLifecycle.Id; } @@ -470,7 +469,6 @@ IEnumerable> ImportProjectChannels(List CheckProjectGroup(ReferenceDataItem projectGroup) { @@ -546,7 +543,12 @@ protected CheckedReferences CheckNuGetFeedsExist(List(); foreach (var nugetFeed in nugetFeeds) { - var feed = Repository.Feeds.FindByName(nugetFeed.Name); + FeedResource feed = null; + if (FeedResourceCustomExpressionHelper.IsValidRepositoryId(nugetFeed.Id)) + feed = Repository.Feeds.FindByName(nugetFeed.Name); + else + feed = FeedResourceCustomExpressionHelper.FeedResourceWithId(nugetFeed.Id); + dependencies.Register(nugetFeed.Name, nugetFeed.Id, feed); } return dependencies; diff --git a/source/Octopus.Cli/Octopus.Cli.csproj b/source/Octopus.Cli/Octopus.Cli.csproj index 1b0966a36..f4344ad69 100644 --- a/source/Octopus.Cli/Octopus.Cli.csproj +++ b/source/Octopus.Cli/Octopus.Cli.csproj @@ -121,6 +121,7 @@ + diff --git a/source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs b/source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs new file mode 100644 index 000000000..367a538b0 --- /dev/null +++ b/source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs @@ -0,0 +1,39 @@ +using Octopus.Client.Model; + +namespace Octopus.Cli.Util +{ + /// + /// Helps with situation where feeds use custom expressions Eg. #{MyCustomFeedURL} + /// + public static class FeedResourceCustomExpressionHelper + { + public static string FeedName = "Custom expression"; + + public static FeedResource FeedResourceWithId(string id) + { + var feed = new FeedResource() + { + Id = id, + Name = FeedResourceCustomExpressionHelper.FeedName + }; + return feed; + } + + /// + /// Helps to check for a valid repository-based feed Id. + /// + /// Feeds may have custom expressions as their Id, which may contain Octostache variable syntax #{MyCustomFeedURL}. + /// If you pass a custom expression Id like this to the API, it will resolve to /api/feeds/, return all the feeds, then + /// attempt to cast that response to a FeedResource object and you'll end up getting an empty FeedResource object instead + /// of null. This method helps you detect valid repository feed objects before running into this confusing API scenario. + /// + /// + /// + public static bool IsValidRepositoryId(string id) + { + if (id.ToLowerInvariant().StartsWith("feeds-")) + return true; + return false; + } + } +} From a9f404b9ed7d4b74250d4f7135730ae2029acc6c Mon Sep 17 00:00:00 2001 From: Mark Siedle Date: Wed, 30 Mar 2016 13:40:51 +1000 Subject: [PATCH 2/5] Adding back a log I accidentally removed --- source/Octopus.Cli/Exporters/ProjectExporter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Octopus.Cli/Exporters/ProjectExporter.cs b/source/Octopus.Cli/Exporters/ProjectExporter.cs index a38f165fe..1ccb184ae 100644 --- a/source/Octopus.Cli/Exporters/ProjectExporter.cs +++ b/source/Octopus.Cli/Exporters/ProjectExporter.cs @@ -83,6 +83,7 @@ protected override void Export(Dictionary parameters) PropertyValueResource nugetFeedId; if (action.Properties.TryGetValue("Octopus.Action.Package.NuGetFeedId", out nugetFeedId)) { + Log.Debug("Finding NuGet feed for step " + step.Name); FeedResource feed = null; if (FeedResourceCustomExpressionHelper.IsValidRepositoryId(nugetFeedId.Value)) feed = Repository.Feeds.Get(nugetFeedId.Value); From 42a2bef9de4582fd256018c5524c7ca97882506e Mon Sep 17 00:00:00 2001 From: Mark Siedle Date: Wed, 30 Mar 2016 13:41:43 +1000 Subject: [PATCH 3/5] whitespace --- source/Octopus.Cli/Exporters/ProjectExporter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/source/Octopus.Cli/Exporters/ProjectExporter.cs b/source/Octopus.Cli/Exporters/ProjectExporter.cs index 1ccb184ae..0c13e6c4a 100644 --- a/source/Octopus.Cli/Exporters/ProjectExporter.cs +++ b/source/Octopus.Cli/Exporters/ProjectExporter.cs @@ -74,7 +74,6 @@ protected override void Export(Dictionary parameters) throw new CouldNotFindException("deployment process for project",project.Name); Log.Debug("Finding NuGet feed for deployment process..."); - var nugetFeeds = new List(); foreach (var step in deploymentProcess.Steps) { From b156dec87f0adb0a10658e82f22e007cc745b790 Mon Sep 17 00:00:00 2001 From: Mark Siedle Date: Wed, 30 Mar 2016 13:44:28 +1000 Subject: [PATCH 4/5] Comment cleanup --- source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs b/source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs index 367a538b0..57b94290a 100644 --- a/source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs +++ b/source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs @@ -3,7 +3,7 @@ namespace Octopus.Cli.Util { /// - /// Helps with situation where feeds use custom expressions Eg. #{MyCustomFeedURL} + /// Helps with situations where feeds use custom expressions Eg. #{MyCustomFeedURL} /// public static class FeedResourceCustomExpressionHelper { From f9438cf795ce88005ecc0f9e7b454e0e5a93e2ec Mon Sep 17 00:00:00 2001 From: Mark Siedle Date: Wed, 30 Mar 2016 14:47:01 +1000 Subject: [PATCH 5/5] Cleaning up the naming and updating the string method for consistency --- source/Octopus.Cli/Exporters/ProjectExporter.cs | 4 ++-- source/Octopus.Cli/Importers/ProjectImporter.cs | 4 ++-- source/Octopus.Cli/Octopus.Cli.csproj | 2 +- ...ssionHelper.cs => FeedCustomExpressionHelper.cs} | 13 +++++++------ 4 files changed, 12 insertions(+), 11 deletions(-) rename source/Octopus.Cli/Util/{FeedResourceCustomExpressionHelper.cs => FeedCustomExpressionHelper.cs} (72%) diff --git a/source/Octopus.Cli/Exporters/ProjectExporter.cs b/source/Octopus.Cli/Exporters/ProjectExporter.cs index 0c13e6c4a..fecc8376f 100644 --- a/source/Octopus.Cli/Exporters/ProjectExporter.cs +++ b/source/Octopus.Cli/Exporters/ProjectExporter.cs @@ -84,10 +84,10 @@ protected override void Export(Dictionary parameters) { Log.Debug("Finding NuGet feed for step " + step.Name); FeedResource feed = null; - if (FeedResourceCustomExpressionHelper.IsValidRepositoryId(nugetFeedId.Value)) + if (FeedCustomExpressionHelper.IsRealFeedId(nugetFeedId.Value)) feed = Repository.Feeds.Get(nugetFeedId.Value); else - feed = FeedResourceCustomExpressionHelper.FeedResourceWithId(nugetFeedId.Value); + feed = FeedCustomExpressionHelper.CustomExpressionFeedWithId(nugetFeedId.Value); if (feed == null) throw new CouldNotFindException("NuGet feed for step", step.Name); diff --git a/source/Octopus.Cli/Importers/ProjectImporter.cs b/source/Octopus.Cli/Importers/ProjectImporter.cs index 38ff2fcdb..80bd1409d 100644 --- a/source/Octopus.Cli/Importers/ProjectImporter.cs +++ b/source/Octopus.Cli/Importers/ProjectImporter.cs @@ -544,10 +544,10 @@ protected CheckedReferences CheckNuGetFeedsExist(List - + diff --git a/source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs b/source/Octopus.Cli/Util/FeedCustomExpressionHelper.cs similarity index 72% rename from source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs rename to source/Octopus.Cli/Util/FeedCustomExpressionHelper.cs index 57b94290a..f1bc7f513 100644 --- a/source/Octopus.Cli/Util/FeedResourceCustomExpressionHelper.cs +++ b/source/Octopus.Cli/Util/FeedCustomExpressionHelper.cs @@ -1,20 +1,21 @@ using Octopus.Client.Model; +using System; namespace Octopus.Cli.Util { /// /// Helps with situations where feeds use custom expressions Eg. #{MyCustomFeedURL} /// - public static class FeedResourceCustomExpressionHelper + public static class FeedCustomExpressionHelper { - public static string FeedName = "Custom expression"; + public static string CustomExpressionFeedName = "Custom expression"; - public static FeedResource FeedResourceWithId(string id) + public static FeedResource CustomExpressionFeedWithId(string id) { var feed = new FeedResource() { Id = id, - Name = FeedResourceCustomExpressionHelper.FeedName + Name = FeedCustomExpressionHelper.CustomExpressionFeedName }; return feed; } @@ -29,9 +30,9 @@ public static FeedResource FeedResourceWithId(string id) /// /// /// - public static bool IsValidRepositoryId(string id) + public static bool IsRealFeedId(string id) { - if (id.ToLowerInvariant().StartsWith("feeds-")) + if (id.StartsWith("feeds-", StringComparison.OrdinalIgnoreCase)) return true; return false; }