support multiple package checks
authorEugene.Petrenko <eugene.petrenko@gmail.com>
Wed, 13 Jul 2011 21:34:02 +0000 (01:34 +0400)
committerEugene.Petrenko <eugene.petrenko@gmail.com>
Wed, 13 Jul 2011 21:34:02 +0000 (01:34 +0400)
nuget-extensions/nuget-commands/nuget-commands.csproj
nuget-extensions/nuget-commands/src/ListCommandBase.cs [new file with mode: 0644]
nuget-extensions/nuget-commands/src/NuGetTeamCityListCommand.cs
nuget-extensions/nuget-commands/src/NuGetTeamCityListPackagesCommand.cs [new file with mode: 0644]
nuget-extensions/nuget-tests/nuget-tests.csproj
nuget-extensions/nuget-tests/src/NuGetRunner_ListPackagesCommandTest.cs [new file with mode: 0644]
nuget-extensions/nuget-tests/src/TempFilesHolder.cs [new file with mode: 0644]

index c73b19f9abc1f6e4f95a462c4595aba4f6638cdc..53193f9371b9d7f0347af5efa680691efd0e6b19 100644 (file)
     <Reference Include="System.Xml" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <Compile Include="src\ListCommandBase.cs" />\r
     <Compile Include="src\NuGetTeamCityListCommand.cs" />\r
     <Compile Include="Properties\AssemblyInfo.cs" />\r
+    <Compile Include="src\NuGetTeamCityListPackagesCommand.cs" />\r
     <Compile Include="src\NuGetTeamCityPingCommand.cs" />\r
     <Compile Include="src\Util\ServiceMessageFormatter.cs" />\r
     <Compile Include="src\Util\ServiceMessageProperty.cs" />\r
diff --git a/nuget-extensions/nuget-commands/src/ListCommandBase.cs b/nuget-extensions/nuget-commands/src/ListCommandBase.cs
new file mode 100644 (file)
index 0000000..9233189
--- /dev/null
@@ -0,0 +1,47 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.ComponentModel.Composition;\r
+using System.Linq;\r
+using System.Linq.Expressions;\r
+using JetBrains.TeamCity.NuGet.ExtendedCommands.Util;\r
+using NuGet;\r
+using NuGet.Commands;\r
+\r
+namespace JetBrains.TeamCity.NuGet.ExtendedCommands\r
+{\r
+  public abstract class ListCommandBase : Command\r
+  {\r
+    [Import]\r
+    public IPackageRepositoryFactory RepositoryFactory { get; set; }\r
+\r
+    [Import]\r
+    public IPackageSourceProvider SourceProvider { get; set; }\r
+\r
+    protected IEnumerable<IPackage> GetAllPackages(string source, IEnumerable<string> ids)\r
+    {\r
+      IPackageRepository packageRepository = RepositoryFactory.CreateRepository(source);\r
+\r
+      var param = Expression.Parameter(typeof (IPackageMetadata));\r
+\r
+      Expression result = Expression.Constant(true);\r
+      foreach (var id in ids)\r
+      {\r
+        result = Expression.Equal(Expression.Property(param, "Id"), Expression.Constant(id));\r
+      }\r
+\r
+      return packageRepository.GetPackages().Where(Expression.Lambda<Func<IPackage, bool>>(result, param));\r
+    }\r
+\r
+    protected static void PrintPackageInfo(IPackage p)\r
+    {\r
+      var msg = ServiceMessageFormatter.FormatMessage(\r
+        "nuget-package",\r
+        new ServiceMessageProperty("Id", p.Id),\r
+        new ServiceMessageProperty("Version", p.Version.ToString())\r
+        );\r
+\r
+      System.Console.Out.WriteLine(msg);\r
+    }\r
+\r
+  }\r
+}
\ No newline at end of file
index 4b1260280d373740c3c1df203706e98b6ce921db..bcef6a0e7adbcc3377e67bb1e8ee60a5ed971d21 100644 (file)
@@ -1,25 +1,15 @@
 ´╗┐using System;\r
 using System.Collections.Generic;\r
-using System.ComponentModel.Composition;\r
 using System.Linq;\r
-using System.Linq.Expressions;\r
-using JetBrains.TeamCity.NuGet.ExtendedCommands.Util;\r
 using NuGet;\r
-using NuGet.Commands;\r
 \r
 namespace JetBrains.TeamCity.NuGet.ExtendedCommands\r
 {\r
   [Command("TeamCity.List", "Lists packages for given Id with parsable output")]\r
-  public class NuGetTeamCityListCommand : Command\r
+  public class NuGetTeamCityListCommand : ListCommandBase\r
   {\r
-    [Import]\r
-    public IPackageRepositoryFactory RepositoryFactory { get; set; }\r
-\r
-    [Import]\r
-    public IPackageSourceProvider SourceProvider { get; set; }\r
-\r
     [Option("NuGet package Source to search for package")]\r
-    public String Source { get; set; }\r
+    public string Source { get; set; }\r
 \r
     [Option("Package Id to check for version update")]\r
     public string Id { get; set; }\r
@@ -32,33 +22,23 @@ namespace JetBrains.TeamCity.NuGet.ExtendedCommands
       System.Console.Out.WriteLine("TeamCity NuGet List command.");\r
       System.Console.Out.WriteLine("Source: {0}", Source ?? "<null>");\r
       System.Console.Out.WriteLine("Package Id: {0}", Id ?? "<null>");\r
-      System.Console.Out.WriteLine("Version: {0}", Version ?? "<null>");\r
-      \r
+      System.Console.Out.WriteLine("Version: {0}", Version ?? "<null>");      \r
       System.Console.Out.WriteLine("Checking for latest version...");\r
-      foreach (var p in GetPackages())\r
-      {\r
-        var msg = ServiceMessageFormatter.FormatMessage(\r
-          "nuget-package",\r
-          new ServiceMessageProperty("Id", p.Id),\r
-          new ServiceMessageProperty("Version", p.Version.ToString())          \r
-          );\r
 \r
-        System.Console.Out.WriteLine(msg);\r
-      }\r
+      foreach (var p in GetPackages())\r
+        PrintPackageInfo(p);\r
     }\r
 \r
     private IEnumerable<IPackage> GetPackages()\r
     {\r
-      IPackageRepository packageRepository = RepositoryFactory.CreateRepository(Source);\r
+      if (string.IsNullOrWhiteSpace(Source))\r
+        throw new CommandLineException("-Source must be specified.");\r
 \r
-      Expression<Func<IPackage, bool>> exp = p => p.Id == Id;\r
-      IQueryable<IPackage> packages = packageRepository\r
-        .GetPackages()\r
-        .Where(exp);\r
+      var allPackages = GetAllPackages(Source, new[] { Id });\r
+      if (string.IsNullOrWhiteSpace(Version))\r
+        return allPackages;\r
 \r
-      if (string.IsNullOrWhiteSpace(Version)) return packages;\r
-      var versionSpec = VersionUtility.ParseVersionSpec(Version);\r
-      return packages.Where(versionSpec.ToDelegate());\r
+      return allPackages.Where(VersionUtility.ParseVersionSpec(Version).ToDelegate());\r
     }\r
   }\r
 }\r
diff --git a/nuget-extensions/nuget-commands/src/NuGetTeamCityListPackagesCommand.cs b/nuget-extensions/nuget-commands/src/NuGetTeamCityListPackagesCommand.cs
new file mode 100644 (file)
index 0000000..359d989
--- /dev/null
@@ -0,0 +1,86 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.IO;\r
+using System.Xml.Serialization;\r
+using NuGet;\r
+using System.Linq;\r
+\r
+namespace JetBrains.TeamCity.NuGet.ExtendedCommands\r
+{\r
+  [Command("TeamCity.ListPackages", "Lists packages for given xml list of packages")]\r
+  public class NuGetTeamCityListPackagesCommand : ListCommandBase\r
+  {\r
+    [Option("Path to file containing package-version pairs to check for updates")]\r
+    public string Request { get; set; }\r
+\r
+    public override void ExecuteCommand()\r
+    {\r
+      var req = LoadRequests();\r
+\r
+      IEnumerable<IPackage> package = GetAllPackages(req.Source, req.Packages.Select(x => x.Id)).ToList();\r
+      var hash = new Dictionary<string, Func<IPackage, bool>>(\r
+        req\r
+          .Packages\r
+          .Where(x => x.LoadVersionSpec() != null)\r
+          .ToDictionary(x => x.Id, x => x.LoadVersionSpec())\r
+        );\r
+\r
+      package = package.Where(x =>\r
+                                {\r
+                                  Func<IPackage, bool> r;\r
+                                  if (!hash.TryGetValue(x.Id, out r))\r
+                                    return true;\r
+                                  return r(x);\r
+                                });\r
+\r
+      foreach (var pkg in package)\r
+      {\r
+        PrintPackageInfo(pkg);\r
+      }\r
+    }\r
+\r
+    private NuGetRequests LoadRequests()\r
+    {\r
+      if (!File.Exists(Request))\r
+        throw new CommandLineException("Failed to find file at {0}", Request);\r
+\r
+      using (var file = File.OpenRead(Request))\r
+      {\r
+        var parser = new XmlSerializerFactory().CreateSerializer(typeof (NuGetRequests));\r
+        return (NuGetRequests) parser.Deserialize(file);\r
+      }\r
+    }\r
+  }\r
+\r
+  [Serializable]\r
+  [XmlRoot("Request")]\r
+  public class NuGetCheckRequest\r
+  {\r
+    private Func<IPackage, bool> myVersionSpec;\r
+\r
+    [XmlAttribute("Id")]\r
+    public string Id { get; set; }\r
+\r
+    [XmlAttribute("Versions")]\r
+    public string VersionSpec { get; set; }\r
+\r
+    public Func<IPackage, bool> LoadVersionSpec()\r
+    {\r
+      return string.IsNullOrWhiteSpace(VersionSpec)\r
+               ? null\r
+               : myVersionSpec ?? (myVersionSpec = VersionUtility.ParseVersionSpec(VersionSpec).ToDelegate());\r
+    }\r
+  }\r
+\r
+  [Serializable]\r
+  [XmlRoot("NuGet-Request")]\r
+  public class NuGetRequests\r
+  {\r
+    [XmlAttribute("Source")]\r
+    public string Source { get; set; }\r
+\r
+    [XmlArray("Requests")]\r
+    [XmlArrayItem("Request")]\r
+    public NuGetCheckRequest[] Packages { get; set; }\r
+  }\r
+}
\ No newline at end of file
index 078ae4af81bec7f42fa95fa7691eb2c4a8dc5d9a..fd251b10c253ca3ccecaf3b6404b79f249387a2c 100644 (file)
@@ -52,7 +52,9 @@
     <Compile Include="src\NuGetRunnerTest.cs" />\r
     <Compile Include="Properties\AssemblyInfo.cs" />\r
     <Compile Include="src\NuGetRunner_ListCommandTest.cs" />\r
+    <Compile Include="src\NuGetRunner_ListPackagesCommandTest.cs" />\r
     <Compile Include="src\ProcessExecutor.cs" />\r
+    <Compile Include="src\TempFilesHolder.cs" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ProjectReference Include="..\nuget-commands\nuget-commands.csproj">\r
diff --git a/nuget-extensions/nuget-tests/src/NuGetRunner_ListPackagesCommandTest.cs b/nuget-extensions/nuget-tests/src/NuGetRunner_ListPackagesCommandTest.cs
new file mode 100644 (file)
index 0000000..ed671d3
--- /dev/null
@@ -0,0 +1,52 @@
+using System.IO;\r
+using NUnit.Framework;\r
+using NuGet;\r
+\r
+namespace JetBrains.TeamCity.NuGet.Tests\r
+{\r
+  [TestFixture]\r
+  public class NuGetRunner_ListPackagesCommandTest\r
+  {\r
+    [Test]\r
+    public void TestCommand_ListPublic()\r
+    {\r
+      TempFilesHolder.WithTempFile(\r
+        file =>\r
+          {\r
+            File.WriteAllText(file,\r
+                              "<NuGet-Request Source=\"" + NuGetConstants.DefaultFeedUrl +\r
+                              "\"><Requests><Request Id='NUnit'/></Requests></NuGet-Request>");\r
+\r
+            ProcessExecutor.ExecuteProcess(NuGetRunner.Path.Value, NuGet.NuGetPath,\r
+                                           "TeamCity.ListPackages", "-Request", file)\r
+              .Dump()\r
+              .AssertExitedSuccessfully()\r
+              .AssertNoErrorOutput()\r
+              .AssertOutputContains("##teamcity[nuget-package Id='NUnit' Version='2.5.7.10213']")\r
+              .AssertOutputContains("##teamcity[nuget-package Id='NUnit' Version='2.5.10.11092']")\r
+              ;\r
+          });\r
+    }\r
+\r
+    [Test]\r
+    public void TestCommand_ListPublicVersions()\r
+    {\r
+      TempFilesHolder.WithTempFile(\r
+        file =>\r
+          {\r
+            File.WriteAllText(file,\r
+                              "<NuGet-Request Source=\"" + NuGetConstants.DefaultFeedUrl +\r
+                              "\"><Requests><Request Id='NUnit' Versions='(1.1.1,2.5.8]'/></Requests></NuGet-Request>");\r
+\r
+            ProcessExecutor.ExecuteProcess(NuGetRunner.Path.Value, NuGet.NuGetPath,\r
+                                           "TeamCity.ListPackages", "-Request", file)\r
+              .Dump()\r
+              .AssertExitedSuccessfully()\r
+              .AssertNoErrorOutput()\r
+              .AssertOutputContains("##teamcity[nuget-package Id='NUnit' Version='2.5.7.10213']")\r
+              ;\r
+          });\r
+    }\r
+\r
+  }\r
+}
\ No newline at end of file
diff --git a/nuget-extensions/nuget-tests/src/TempFilesHolder.cs b/nuget-extensions/nuget-tests/src/TempFilesHolder.cs
new file mode 100644 (file)
index 0000000..67445c7
--- /dev/null
@@ -0,0 +1,20 @@
+using System;\r
+using System.IO;\r
+\r
+namespace JetBrains.TeamCity.NuGet.Tests\r
+{\r
+  public static class TempFilesHolder\r
+  {\r
+    public static void WithTempFile(Action<string> action)\r
+    {\r
+      string tmp = Path.GetTempFileName();\r
+      try\r
+      {\r
+        action(tmp);\r
+      } finally\r
+      {\r
+        File.Delete(tmp);\r
+      }\r
+    }\r
+  }\r
+}
\ No newline at end of file