watch nuget tool changes
authorEugene Petrenko <eugene.petrenko@gmail.com>
Tue, 16 Aug 2011 12:54:02 +0000 (16:54 +0400)
committerEugene Petrenko <eugene.petrenko@gmail.com>
Tue, 16 Aug 2011 12:54:02 +0000 (16:54 +0400)
14 files changed:
nuget-server/fake-teamcity-server-plugin-context.xml
nuget-server/src/META-INF/build-server-plugin-nuget-tools.xml
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/AgentToolsRegistrar.java [new file with mode: 0644]
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/InstallLogger.java
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/NuGetToolsInstaller.java
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/PluginNaming.java
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolPacker.java
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolPaths.java
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolPathsImpl.java
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolUnpacker.java [new file with mode: 0644]
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolsRegistry.java
nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolsWatcher.java [new file with mode: 0644]
nuget-tests/src/jetbrains/buildServer/nuget/tests/server/tools/NuGetToolsInstallerTest.java
nuget-tests/src/jetbrains/buildServer/nuget/tests/server/tools/ToolPackerTest.java

index 888f5d40b46a4c0960608e9bd066928d1ccb8e3b..64b135b4438aebf7ab78868e201357054fea3398 100644 (file)
@@ -7,4 +7,5 @@
   <!-- this is a fake spring context xml to make IDEA know all implicit beans that are available for plugin -->\r
   <bean class="jetbrains.buildServer.web.openapi.PluginDescriptor"/>\r
   <bean class="jetbrains.buildServer.plugins.bean.PluginInfo"/>\r
+  <bean class="jetbrains.buildServer.serverSide.ServerPaths"/>\r
 </beans>
\ No newline at end of file
index 59c2c3461603583cc45d9016b50403608fa711b9..59081ea8f9d083a9c04467585db79ea98c12b688 100644 (file)
   <bean class="jetbrains.buildServer.nuget.server.toolRegistry.impl.NuGetToolsInstaller"/>\r
   <bean class="jetbrains.buildServer.nuget.server.toolRegistry.impl.ToolsRegistry"/>\r
   <bean class="jetbrains.buildServer.nuget.server.toolRegistry.impl.ToolPacker"/>\r
+  <bean class="jetbrains.buildServer.nuget.server.toolRegistry.impl.ToolUnpacker"/>\r
   <bean class="jetbrains.buildServer.nuget.server.toolRegistry.impl.ToolPathsImpl"/>\r
   <bean class="jetbrains.buildServer.nuget.server.toolRegistry.impl.PluginNaming"/>\r
+\r
+  <bean class="jetbrains.buildServer.nuget.server.toolRegistry.impl.AgentToolsRegistrar"/>\r
+  <bean class="jetbrains.buildServer.nuget.server.toolRegistry.impl.ToolsWatcher" init-method="start" destroy-method="dispose"/>\r
 </beans>
\ No newline at end of file
diff --git a/nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/AgentToolsRegistrar.java b/nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/AgentToolsRegistrar.java
new file mode 100644 (file)
index 0000000..ff7891d
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.toolRegistry.impl;\r
+\r
+import jetbrains.buildServer.serverSide.impl.agent.AgentPluginsHolder;\r
+import jetbrains.buildServer.serverSide.impl.agent.AgentPluginsHolderBase;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.io.File;\r
+\r
+/**\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 16.08.11 15:21\r
+ */\r
+public class AgentToolsRegistrar {\r
+  public AgentToolsRegistrar(@NotNull final AgentPluginsHolder holder,\r
+                             @NotNull final ToolPaths paths) {\r
+    holder.addAgentPlugins(new AgentPluginsHolderBase() {\r
+      @Override\r
+      protected File getAgentPluginsDirectory() {\r
+        return paths.getAgentPluginsPath();\r
+      }\r
+    });\r
+  }\r
+}\r
index 57e045bf0ea2bf0f537289f134c3e95f0a003727..09b18e0431334709890c4a6d4f3ad6a62c453e0a 100644 (file)
@@ -33,9 +33,9 @@ public interface InstallLogger {
 \r
   void packageDownloadStarted(@NotNull FeedPackage tool);\r
 \r
-  void packageDownloadFinished(@NotNull FeedPackage tool, @Nullable File pkg);\r
+  void packageDownloadFinished(@NotNull FeedPackage tool);\r
 \r
-  void packageDownloadFailed(@NotNull FeedPackage tool, @Nullable File pkg, @NotNull Exception e);\r
+  void packageDownloadFailed(@NotNull FeedPackage tool, @NotNull Exception e);\r
 \r
   void packageUnpackStarted(@NotNull FeedPackage tool, @NotNull File pkg);\r
 \r
index 2d244bce5210296cc944b79d403a17fb600a081e..935c304e7833cb3b8c65cc26919b9babb7bc7291 100644 (file)
@@ -19,12 +19,11 @@ package jetbrains.buildServer.nuget.server.toolRegistry.impl;
 import com.intellij.openapi.diagnostic.Logger;\r
 import jetbrains.buildServer.nuget.server.feed.reader.FeedPackage;\r
 import jetbrains.buildServer.nuget.server.feed.reader.NuGetFeedReader;\r
-import jetbrains.buildServer.util.ArchiveUtil;\r
 import jetbrains.buildServer.util.FileUtil;\r
 import org.jetbrains.annotations.NotNull;\r
 \r
-import java.io.*;\r
-import java.util.zip.ZipInputStream;\r
+import java.io.File;\r
+import java.io.IOException;\r
 \r
 /**\r
  * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
@@ -36,19 +35,16 @@ public class NuGetToolsInstaller {
   private final ToolPaths myToolPaths;\r
   private final NuGetFeedReader myClient;\r
   private final AvailableToolsState myState;\r
-  private final ToolPacker myPacker;\r
-  private final PluginNaming myNaming;\r
+  private final ToolsWatcher myWatcher;\r
 \r
   public NuGetToolsInstaller(@NotNull final ToolPaths toolPaths,\r
                              @NotNull final NuGetFeedReader client,\r
                              @NotNull final AvailableToolsState state,\r
-                             @NotNull final ToolPacker packer,\r
-                             @NotNull final PluginNaming naming) {\r
+                             @NotNull final ToolsWatcher watcher) {\r
     myToolPaths = toolPaths;\r
     myClient = client;\r
     myState = state;\r
-    myPacker = packer;\r
-    myNaming = naming;\r
+    myWatcher = watcher;\r
   }\r
 \r
   public void installNuGet(@NotNull final String packageId, @NotNull final InstallLogger logger) {\r
@@ -62,98 +58,27 @@ public class NuGetToolsInstaller {
         return;\r
       }\r
 \r
-      final File pkg = downloadPackage(logger, tool);\r
-      final File dest = extractPackage(logger, tool, pkg);\r
-      File agentTool = packAgentPlugin(logger, tool, dest);\r
-      registerAgentPlugins(logger, tool, agentTool);\r
-    } catch (ProcessedException e) {\r
-      //NOP;\r
+      logger.packageDownloadStarted(tool);\r
+      File dest = new File(myToolPaths.getPackages(), tool.getInfo().getId() + "." + tool.getInfo().getVersion() + ".nupkg");\r
+      try {\r
+        File tmp = File.createTempFile(dest.getName(), ".nupkg");\r
+        FileUtil.createParentDirs(tmp);\r
+        myClient.downloadPackage(tool, tmp);\r
+        if (!tmp.renameTo(dest)) {\r
+          throw new IOException("Failed to plug downloaded package to " + dest);\r
+        }\r
+      } catch (Exception e) {\r
+        LOG.warn("Failed to download package " + tool + ". " + e.getMessage(), e);\r
+        logger.packageDownloadFailed(tool, e);\r
+        return;\r
+      } finally {\r
+        logger.packageDownloadFinished(tool);\r
+      }\r
+      myWatcher.checkNow();\r
     } catch (Exception e) {\r
       LOG.warn("Failed to install NuGet.Commandline package. " + e.getMessage(), e);\r
     } finally {\r
       logger.finished(packageId, tool);\r
     }\r
   }\r
-\r
-  @NotNull\r
-  private File registerAgentPlugins(InstallLogger logger, FeedPackage tool, File agentTool) {\r
-    logger.agentToolPublishStarted(tool, agentTool);\r
-\r
-    try {\r
-      final File dest = myNaming.getAgetToolFilePath(tool);\r
-      if (!agentTool.renameTo(dest)) {\r
-        FileUtil.copy(agentTool, dest);\r
-        FileUtil.delete(agentTool);\r
-      }\r
-      return dest;\r
-    } catch (Exception e) {\r
-      logger.agentToolPublishFailed(tool, agentTool, e);\r
-      throw new ProcessedException();\r
-    } finally {\r
-      logger.agentToolPublishFinished(tool, agentTool);\r
-    }\r
-  }\r
-\r
-  private String getAgentToolFileName(@NotNull String version) {\r
-    return "nuget-commnadline-" + version;\r
-  }\r
-\r
-  private File packAgentPlugin(@NotNull final InstallLogger logger,\r
-                               @NotNull final FeedPackage tool,\r
-                               @NotNull final File dest) {\r
-    logger.agentToolPackStarted(tool, dest);\r
-    try {\r
-      return myPacker.packTool(getAgentToolFileName(tool.getInfo().getVersion()), dest);\r
-    } catch (Exception e) {\r
-      logger.agentToolPackFailed(tool, dest, e);\r
-      LOG.warn("Failed to pack agent tool " + tool);\r
-      throw new ProcessedException();\r
-    } finally {\r
-      logger.agentToolPackFinished(tool);\r
-    }\r
-  }\r
-\r
-  @NotNull\r
-  private File extractPackage(@NotNull final InstallLogger logger,\r
-                              @NotNull final FeedPackage tool,\r
-                              @NotNull final File pkg) {\r
-    logger.packageUnpackStarted(tool, pkg);\r
-    File dest = null;\r
-    try {\r
-      dest = new File(myToolPaths.getTools(), tool.getInfo().getVersion());\r
-      FileUtil.createDir(dest);\r
-      final ZipInputStream zip = new ZipInputStream(new BufferedInputStream(new FileInputStream(pkg)));\r
-      if (!ArchiveUtil.unpackZip(zip, dest)) {\r
-        throw new IOException("Failed to unpack package " + tool.getInfo() + " to " + dest);\r
-      }\r
-      return dest;\r
-    } catch (Exception e) {\r
-      logger.packageUnpackFailed(tool, pkg, dest);\r
-      LOG.warn("Failed to unpack nuget package " + tool + ". " + e.getMessage(), e);\r
-      throw new ProcessedException();\r
-    } finally {\r
-      logger.packageUnpackFinished(tool, pkg, dest);\r
-    }\r
-  }\r
-\r
-  @NotNull\r
-  private File downloadPackage(@NotNull final InstallLogger logger,\r
-                               @NotNull final FeedPackage tool) {\r
-    logger.packageDownloadStarted(tool);\r
-    File pkg = null;\r
-    try {\r
-      pkg = FileUtil.createTempFile("nuget.commandline", ".nupkg");\r
-      myClient.downloadPackage(tool, pkg);\r
-      return pkg;\r
-    } catch (Exception e) {\r
-      LOG.warn("Failed to download package " + tool + (pkg != null ? " to file " + pkg : ""));\r
-      logger.packageDownloadFailed(tool, pkg, e);\r
-      throw new ProcessedException();\r
-    } finally {\r
-      logger.packageDownloadFinished(tool, pkg);\r
-    }\r
-  }\r
-\r
-  private static class ProcessedException extends RuntimeException {\r
-  }\r
 }\r
index 02c65e179c511b472977ad9cb7edfcf4afea3bc3..931e5ccb4b39314fcd0e41290ea670729296b3d0 100644 (file)
 \r
 package jetbrains.buildServer.nuget.server.toolRegistry.impl;\r
 \r
-import jetbrains.buildServer.nuget.common.PackagesConstants;\r
-import jetbrains.buildServer.nuget.server.feed.reader.FeedPackage;\r
-import jetbrains.buildServer.nuget.server.toolRegistry.NuGetTool;\r
+import jetbrains.buildServer.util.StringUtil;\r
 import org.jetbrains.annotations.NotNull;\r
 \r
 import java.io.File;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
 \r
 /**\r
  * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
@@ -35,16 +35,25 @@ public class PluginNaming {
   }\r
 \r
   @NotNull\r
-  private String getAgentToolFileName(@NotNull String version) {\r
-    return PackagesConstants.NUGET_TOOL_NAME_PREFIX + version + ".zip";\r
+  public File getUnpackedFolder(@NotNull final File packageFile) {\r
+    //here we could take a look into .nuspec to fetch version and name\r
+    return new File(myPaths.getTools(), packageFile.getName());\r
   }\r
 \r
-  public File getAgentToolFilePath(@NotNull NuGetTool tool) {\r
-    return new File(myPaths.getAgentPluginsPath(), getAgentToolFileName(tool.getVersion()));\r
+  @NotNull\r
+  public File getAgentFile(@NotNull final File packageFile) {\r
+    //here we could take a look into .nuspec to fetch version and name\r
+    return new File(myPaths.getAgentPluginsPath(), packageFile.getName() + ".zip");\r
   }\r
 \r
-  public File getAgetToolFilePath(@NotNull FeedPackage tool) {\r
-    return new File(myPaths.getAgentPluginsPath(), getAgentToolFileName(tool.getInfo().getVersion()));\r
+  @NotNull\r
+  public String getVersion(@NotNull final File plugin) {\r
+    Pattern pt = Pattern.compile("\\d+(\\.\\d+)+");\r
+    final Matcher matcher = pt.matcher(plugin.getName());\r
+    String match = "N/A";\r
+    while (matcher.find()) {\r
+      match = matcher.group();\r
+    }\r
+    return StringUtil.isEmptyOrSpaces(match) ? "N/A" : match;\r
   }\r
-\r
 }\r
index 661a1af1dba817264a7659d16dd78352bd915761..6c6edc231132054346909f51b9d7957260d4c690 100644 (file)
@@ -33,9 +33,8 @@ import java.util.zip.ZipOutputStream;
  */\r
 public class ToolPacker {\r
 \r
-  public File packTool(@NotNull final String toolId,\r
-                       @NotNull final File rootDir) throws IOException {\r
-    final File tool = new File(FileUtil.getTempDirectory(), toolId + ".zip");\r
+  public void packTool(@NotNull final File tool, @NotNull final File rootDir) throws IOException {\r
+    FileUtil.createParentDirs(tool);\r
     final ZipOutputStream fos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tool)));\r
     try {\r
       fos.putNextEntry(new ZipEntry("teamcity-plugin.xml"));\r
@@ -47,8 +46,6 @@ public class ToolPacker {
     } finally {\r
       FileUtil.close(fos);\r
     }\r
-\r
-    return tool;\r
   }\r
 \r
   private static final String TOOL_DESCRIPTOR = "" +\r
index aa85ebf2147cf49afa8e0b5b59c334363e8ece4c..31cc6b9d4a0dc185ec275d1f70fd38c675485b23 100644 (file)
@@ -1,3 +1,19 @@
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
 package jetbrains.buildServer.nuget.server.toolRegistry.impl;\r
 \r
 import org.jetbrains.annotations.NotNull;\r
@@ -13,4 +29,7 @@ public interface ToolPaths {
   File getTools();\r
 \r
   File getAgentPluginsPath();\r
+\r
+  @NotNull\r
+  File getPackages();\r
 }\r
index b578807ef112300f9b43f08c5611a6cf6ce3ca5f..0a61d41e22308fe762f2117e6126c4b2efed6203 100644 (file)
@@ -16,8 +16,7 @@
 \r
 package jetbrains.buildServer.nuget.server.toolRegistry.impl;\r
 \r
-import jetbrains.buildServer.plugins.bean.PluginInfo;\r
-import jetbrains.buildServer.web.openapi.PluginDescriptor;\r
+import jetbrains.buildServer.serverSide.ServerPaths;\r
 import org.jetbrains.annotations.NotNull;\r
 \r
 import java.io.File;\r
@@ -29,20 +28,28 @@ import java.io.File;
 public class ToolPathsImpl implements ToolPaths {\r
   private final File myPluginRoot;\r
 \r
-  public ToolPathsImpl(@NotNull final PluginDescriptor paths) {\r
-    myPluginRoot = ((PluginInfo)paths).getPluginRoot();\r
+  public ToolPathsImpl(@NotNull final ServerPaths paths) {\r
+    myPluginRoot = new File(paths.getPluginDataDirectory(), "jetbrains.nuget");\r
+  }\r
+\r
+  private File relative(@NotNull final String path) {\r
+    final File pkgs = new File(myPluginRoot, path);\r
+    //noinspection ResultOfMethodCallIgnored\r
+    pkgs.mkdirs();\r
+    return pkgs;\r
+  }\r
+\r
+  @NotNull\r
+  public File getPackages() {\r
+    return relative("nupkg");\r
   }\r
 \r
   @NotNull\r
   public File getTools() {\r
-    final File file = new File(myPluginRoot, "tools");\r
-    file.mkdirs();\r
-    return file;\r
+    return relative("tools");\r
   }\r
 \r
   public File getAgentPluginsPath() {\r
-    final File file = new File(myPluginRoot, "agent");\r
-    file.mkdirs();\r
-    return file;\r
+    return relative("agent");\r
   }\r
 }\r
diff --git a/nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolUnpacker.java b/nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolUnpacker.java
new file mode 100644 (file)
index 0000000..c43d21d
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.toolRegistry.impl;\r
+\r
+import jetbrains.buildServer.util.ArchiveUtil;\r
+import jetbrains.buildServer.util.FileUtil;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
+import java.util.zip.ZipInputStream;\r
+\r
+/**\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 16.08.11 15:11\r
+ */\r
+public class ToolUnpacker {\r
+  public void extractPackage(@NotNull final File pkg,\r
+                             @NotNull final File dest) throws IOException {\r
+    FileUtil.createDir(dest);\r
+    final ZipInputStream zip = new ZipInputStream(new BufferedInputStream(new FileInputStream(pkg)));\r
+    if (!ArchiveUtil.unpackZip(zip, dest)) {\r
+      throw new IOException("Failed to unpack package " + pkg + " to " + dest);\r
+    }\r
+  }\r
+}\r
index 57198d5581bed4f3f34312cb1b4ff0d564c95879..50dd816cb5c8a894842251c472145a2a7718f18c 100644 (file)
@@ -23,6 +23,7 @@ import jetbrains.buildServer.util.FileUtil;
 import org.jetbrains.annotations.NotNull;\r
 \r
 import java.io.File;\r
+import java.io.FileFilter;\r
 import java.util.ArrayList;\r
 import java.util.Collection;\r
 import java.util.Collections;\r
@@ -33,13 +34,17 @@ import java.util.Collections;
  */\r
 public class ToolsRegistry {\r
   private static final Logger LOG = Logger.getInstance(ToolsRegistry.class.getName());\r
+\r
   private final ToolPaths myPaths;\r
   private final PluginNaming myNaming;\r
+  private final ToolsWatcher myWatcher;\r
 \r
   public ToolsRegistry(@NotNull final ToolPaths paths,\r
-                       @NotNull final PluginNaming naming) {\r
+                       @NotNull final PluginNaming naming,\r
+                       @NotNull final ToolsWatcher watcher) {\r
     myPaths = paths;\r
     myNaming = naming;\r
+    myWatcher = watcher;\r
   }\r
 \r
   @NotNull\r
@@ -48,17 +53,18 @@ public class ToolsRegistry {
   }\r
 \r
   private Collection<InstalledTool> getToolsInternal() {\r
-    final File[] tools = myPaths.getTools().listFiles();\r
+    final File[] tools = myPaths.getPackages().listFiles(IS_PACKAGE);\r
     if (tools == null) return Collections.emptyList();\r
+\r
     final Collection<InstalledTool> result = new ArrayList<InstalledTool>();\r
     for (final File path : tools) {\r
-      final InstalledTool e = new InstalledTool(path);\r
+      final InstalledTool e = new InstalledTool(myNaming, path);\r
       if (!e.getPath().isFile()) {\r
         LOG.warn("NuGet.exe is not found at " + e);\r
         continue;\r
       }\r
 \r
-      if (!myNaming.getAgentToolFilePath(e).isFile()) {\r
+      if (!e.getAgentPluginFile().isFile()) {\r
         LOG.warn("NuGet tool is not packed for agent. " + e);\r
         continue;\r
       }\r
@@ -71,44 +77,43 @@ public class ToolsRegistry {
     for (InstalledTool tool : getToolsInternal()) {\r
       if (tool.getId().equals(toolId)) {\r
         LOG.info("Removing NuGet plugin: " + tool);\r
-\r
-        final File agentPlugin = myNaming.getAgentToolFilePath(tool);\r
-        LOG.info("Removing NuGet plugin agent tool : " + agentPlugin);\r
-        FileUtil.delete(agentPlugin);\r
-\r
-        final File toolHome = tool.getRootPath();\r
-        LOG.info("Removing NuGet files from: " + toolHome);\r
-        FileUtil.delete(toolHome);\r
-        return;\r
+        tool.delete();\r
       }\r
     }\r
+    myWatcher.checkNow();\r
   }\r
 \r
   private static class InstalledTool implements NuGetInstalledTool {\r
+    private final PluginNaming myNaming;\r
     private final File myPath;\r
 \r
-    public InstalledTool(@NotNull final File path) {\r
+    public InstalledTool(PluginNaming naming, @NotNull final File path) {\r
+      myNaming = naming;\r
       myPath = path;\r
     }\r
 \r
     @NotNull\r
-    public File getRootPath() {\r
-      return myPath;\r
+    public File getPath() {\r
+      return FileUtil.getCanonicalFile(new File(myNaming.getUnpackedFolder(myPath), PackagesConstants.NUGET_TOOL_REL_PATH));\r
     }\r
 \r
     @NotNull\r
-    public File getPath() {\r
-      return FileUtil.getCanonicalFile(new File(myPath, PackagesConstants.NUGET_TOOL_REL_PATH));\r
+    public File getAgentPluginFile() {\r
+      return FileUtil.getCanonicalFile(myNaming.getAgentFile(myPath));\r
+    }\r
+\r
+    public void delete() {\r
+      FileUtil.delete(myPath);\r
     }\r
 \r
     @NotNull\r
     public String getId() {\r
-      return myPath.getName();\r
+      return getVersion();\r
     }\r
 \r
     @NotNull\r
     public String getVersion() {\r
-      return myPath.getName();\r
+      return myNaming.getVersion(myPath);\r
     }\r
 \r
     @Override\r
@@ -118,4 +123,11 @@ public class ToolsRegistry {
               '}';\r
     }\r
   }\r
+\r
+  private final FileFilter IS_PACKAGE = new FileFilter() {\r
+    public boolean accept(File pathname) {\r
+      return pathname.isFile() && pathname.getName().endsWith(".nupkg");\r
+    }\r
+  };\r
+\r
 }\r
diff --git a/nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolsWatcher.java b/nuget-server/src/jetbrains/buildServer/nuget/server/toolRegistry/impl/ToolsWatcher.java
new file mode 100644 (file)
index 0000000..af99d30
--- /dev/null
@@ -0,0 +1,128 @@
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.toolRegistry.impl;\r
+\r
+import com.intellij.openapi.diagnostic.Logger;\r
+import jetbrains.buildServer.configuration.ChangeListener;\r
+import jetbrains.buildServer.configuration.FilesWatcher;\r
+import jetbrains.buildServer.util.FileUtil;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 16.08.11 13:24\r
+ */\r
+public class ToolsWatcher {\r
+  private static final Logger LOG = Logger.getInstance(ToolsWatcher.class.getName());\r
+\r
+  private final ToolPaths myPaths;\r
+  private final ToolPacker myPacker;\r
+  private final ToolUnpacker myUnpacker;\r
+  private final FilesWatcher myWatcher;\r
+\r
+  public ToolsWatcher(@NotNull final ToolPaths paths,\r
+                      @NotNull final ToolPacker packer,\r
+                      @NotNull final ToolUnpacker unpacker) {\r
+    myPaths = paths;\r
+    myPacker = packer;\r
+    myUnpacker = unpacker;\r
+    myWatcher = new FilesWatcher(new FilesWatcher.WatchedFilesProvider() {\r
+      public File[] getWatchedFiles() {\r
+        return myPaths.getPackages().listFiles();\r
+      }\r
+    });\r
+    myWatcher.registerListener(new ChangeListener() {\r
+      public void changeOccured(String requestor) {\r
+        ToolsWatcher.this.onFilesChanged(\r
+                myWatcher.getModifiedFiles(),\r
+                myWatcher.getNewFiles(),\r
+                myWatcher.getRemovedFiles());\r
+      }\r
+    });\r
+    myWatcher.setSleepingPeriod(10000);\r
+  }\r
+\r
+  public void setSleepingPeriod(int time) {\r
+    myWatcher.setSleepingPeriod(time);\r
+  }\r
+\r
+  public void start() {\r
+    myWatcher.start();\r
+  }\r
+\r
+  public void dispose() {\r
+    myWatcher.stop();\r
+  }\r
+\r
+  public void checkNow() {\r
+    myWatcher.checkForModifications();\r
+  }\r
+\r
+  private void onFilesChanged(List<File> modified, List<File> added, List<File> removed) {\r
+    for (File file : join(modified, removed)) {\r
+      removePackage(file, getAgentFile(file), getUnpackedFolder(file));\r
+    }\r
+\r
+    for (File file : join(modified, added)) {\r
+      installPackage(file, getAgentFile(file), getUnpackedFolder(file));\r
+    }\r
+  }\r
+\r
+  private void installPackage(@NotNull final File file, File agentFile, File unpackedFolder) {\r
+    try {\r
+      FileUtil.createParentDirs(agentFile);\r
+      FileUtil.createDir(unpackedFolder);\r
+\r
+      myUnpacker.extractPackage(file, unpackedFolder);\r
+      myPacker.packTool(agentFile, unpackedFolder);\r
+    } catch (Throwable t){\r
+      LOG.warn("Failed to unpack nuget commandline: " + file);\r
+    }\r
+  }\r
+\r
+  private void removePackage(@NotNull final File file, File agentFile, File unpackedFolder) {\r
+    LOG.info("Removing NuGet package: " + file.getName());\r
+    FileUtil.delete(file);\r
+    FileUtil.delete(agentFile);\r
+    FileUtil.delete(unpackedFolder);\r
+  }\r
+\r
+  @NotNull\r
+  private <T> Collection<T> join(@NotNull Collection<T> a, @NotNull Collection<T> b) {\r
+    ArrayList<T> list = new ArrayList<T>(a.size() + b.size());\r
+    list.addAll(a);\r
+    list.addAll(b);\r
+    return list;\r
+  }\r
+\r
+  @NotNull\r
+  private File getUnpackedFolder(@NotNull final File packages) {\r
+    //here we could take a look into .nuspec to fetch version and name\r
+    return new File(myPaths.getTools(), packages.getName());\r
+  }\r
+\r
+  @NotNull\r
+  private File getAgentFile(@NotNull final File packages) {\r
+    //here we could take a look into .nuspec to fetch version and name\r
+    return new File(myPaths.getAgentPluginsPath(), packages.getName() + ".zip");\r
+  }\r
+}\r
index f0e0b3ed31b3ba8457cae9ae4285bbd86fd8fdef..10fbc816b7cc8c35c0eb5bcdb4c901517cdcd1c0 100644 (file)
@@ -58,9 +58,11 @@ public class NuGetToolsInstallerTest extends BaseTestCase {
             myPaths,\r
             myFeed,\r
             myState,\r
-            new ToolPacker(),\r
-            new PluginNaming(myPaths)\r
-    );\r
+            new ToolsWatcher(\r
+                    myPaths,\r
+                    new ToolPacker(),\r
+                    new ToolUnpacker()\r
+            ));\r
 \r
     m.checking(new Expectations(){{\r
       allowing(myPaths).getTools(); will(returnValue(myToolsPath));\r
@@ -90,7 +92,7 @@ public class NuGetToolsInstallerTest extends BaseTestCase {
 \r
       oneOf(myLogger).started("pkd");\r
       oneOf(myLogger).packageDownloadStarted(pkd);\r
-      oneOf(myLogger).packageDownloadFinished(with(equal(pkd)), with(any(File.class)));\r
+      oneOf(myLogger).packageDownloadFinished(with(equal(pkd)));\r
       oneOf(myLogger).packageUnpackStarted(with(equal(pkd)), with(any(File.class)));\r
       oneOf(myLogger).packageUnpackFinished(with(equal(pkd)), with(any(File.class)), with(any(File.class)));\r
 \r
index d84f397c4e712f93757c980df89b0356695374a9..2a747c3caeb966d54e978b56f8ad231edef3ed05 100644 (file)
@@ -47,29 +47,30 @@ public class ToolPackerTest extends BaseTestCase {
 \r
   @Test\r
   public void testPack() throws IOException {\r
-    final String toolId = "3.4.56.3";\r
     final File root = createTempDir();\r
-    final File plugin = myPacker.packTool(toolId, root);\r
+    final File plugin = createTempFile();\r
+    myPacker.packTool(plugin, root);\r
 \r
     assertZip(plugin, "teamcity-plugin.xml");\r
   }\r
 \r
   @Test\r
   public void testPack_oneFile() throws IOException {\r
-    final String toolId = "3.4.56.3";\r
     final File root = createTempDir();\r
     FileUtil.writeFile(new File(root, "aaa.txt"), "content");\r
-    final File plugin = myPacker.packTool(toolId, root);\r
+    final File plugin = createTempFile();\r
+    myPacker.packTool(plugin, root);\r
+\r
 \r
     assertZip(plugin, "teamcity-plugin.xml", "aaa.txt");\r
   }\r
 \r
   @Test\r
   public void testPack_oneFile2() throws IOException {\r
-    final String toolId = "3.4.56.3";\r
     final File root = createTempDir();\r
     FileUtil.writeFile(new File(root, "a/b/c/d/aaa.txt"){{getParentFile().mkdirs();}}, "content");\r
-    final File plugin = myPacker.packTool(toolId, root);\r
+    final File plugin = createTempFile();\r
+    myPacker.packTool(plugin, root);\r
 \r
     assertZip(plugin, "teamcity-plugin.xml", "a/b/c/d/aaa.txt");\r
   }\r