Mercurial > hg > tc-symbol-server
comparison agent/src/jetbrains/buildServer/symbols/SymbolsIndexer.java @ 2:c6ca0a26d93e
initial implementation of agent-side symbol indexer
author | Evgeniy.Koshkin |
---|---|
date | Thu, 18 Jul 2013 15:34:28 +0400 |
parents | |
children | 53028ba390e0 |
comparison
equal
deleted
inserted
replaced
1:33e8cf5b2d57 | 2:c6ca0a26d93e |
---|---|
1 package jetbrains.buildServer.symbols; | |
2 | |
3 import com.intellij.execution.configurations.GeneralCommandLine; | |
4 import jetbrains.buildServer.ExecResult; | |
5 import jetbrains.buildServer.SimpleCommandLineProcessRunner; | |
6 import jetbrains.buildServer.agent.AgentLifeCycleAdapter; | |
7 import jetbrains.buildServer.agent.AgentLifeCycleListener; | |
8 import jetbrains.buildServer.agent.AgentRunningBuild; | |
9 import jetbrains.buildServer.agent.BuildFinishedStatus; | |
10 import jetbrains.buildServer.agent.artifacts.ArtifactsWatcher; | |
11 import jetbrains.buildServer.agent.impl.artifacts.ArtifactsBuilderAdapter; | |
12 import jetbrains.buildServer.agent.impl.artifacts.ArtifactsCollection; | |
13 import jetbrains.buildServer.agent.plugins.beans.PluginDescriptor; | |
14 import jetbrains.buildServer.util.EventDispatcher; | |
15 import jetbrains.buildServer.util.FileUtil; | |
16 import org.apache.log4j.Logger; | |
17 import org.jetbrains.annotations.NotNull; | |
18 import org.jetbrains.annotations.Nullable; | |
19 | |
20 import java.io.File; | |
21 import java.io.IOException; | |
22 import java.util.*; | |
23 | |
24 /** | |
25 * @author Evgeniy.Koshkin | |
26 */ | |
27 public class SymbolsIndexer extends ArtifactsBuilderAdapter { | |
28 | |
29 public static final Logger LOG = Logger.getLogger(SymbolsIndexer.class); | |
30 | |
31 public static final String PDB_FILE_EXTENSION = "pdb"; | |
32 public static final String EXE_FILE_EXTENSION = "exe"; | |
33 public static final String DLL_FILE_EXTENSION = "dll"; | |
34 | |
35 public static final String SYMBOLS_EXE = "symbols.exe"; | |
36 public static final String DUMP_SYMBOL_SIGN_CMD = "dumpSymbolSign"; | |
37 public static final String DUMP_BIN_SIGN_CMD = "dumpBinSign"; | |
38 | |
39 @NotNull private final ArtifactsWatcher myArtifactsWatcher; | |
40 @NotNull private final File myNativeToolPath; | |
41 @Nullable private AgentRunningBuild myBuild; | |
42 @Nullable private Collection<File> myBinariesToProcess; | |
43 @Nullable private Collection<File> mySymbolsToProcess; | |
44 | |
45 public SymbolsIndexer(@NotNull final PluginDescriptor pluginDescriptor, @NotNull final EventDispatcher<AgentLifeCycleListener> agentDispatcher, @NotNull final ArtifactsWatcher artifactsWatcher) { | |
46 myNativeToolPath = new File(new File(pluginDescriptor.getPluginRoot(), "bin"), SYMBOLS_EXE); | |
47 myArtifactsWatcher = artifactsWatcher; | |
48 agentDispatcher.addListener(new AgentLifeCycleAdapter() { | |
49 @Override | |
50 public void buildStarted(@NotNull final AgentRunningBuild runningBuild) { | |
51 myBuild = runningBuild; | |
52 myBinariesToProcess = new HashSet<File>(); | |
53 mySymbolsToProcess = new HashSet<File>(); | |
54 } | |
55 | |
56 @Override | |
57 public void beforeBuildFinish(@NotNull AgentRunningBuild build, @NotNull BuildFinishedStatus buildStatus) { | |
58 super.beforeBuildFinish(build, buildStatus); | |
59 if (myBuild == null || mySymbolsToProcess == null || myBinariesToProcess == null) return; | |
60 if (mySymbolsToProcess.isEmpty()) { | |
61 LOG.debug("Symbols weren't found in artifacts to be published."); | |
62 } else { | |
63 final File targetDir = myBuild.getBuildTempDirectory(); | |
64 try { | |
65 final File symbolSignaturesFile = dumpSymbolSignatures(mySymbolsToProcess, targetDir); | |
66 myArtifactsWatcher.addNewArtifactsPath(symbolSignaturesFile + "=>" + ".teamcity/symbols/symbol-signatures.xml"); | |
67 final File binariesSignaturesFile = dumpBinarySignatures(myBinariesToProcess, targetDir); | |
68 myArtifactsWatcher.addNewArtifactsPath(binariesSignaturesFile + "=>" + ".teamcity/symbols/binary-signatures.xml"); | |
69 } catch (IOException e) { | |
70 LOG.error("Error while dumping symbols/binaries signatures.", e); | |
71 } | |
72 } | |
73 mySymbolsToProcess = null; | |
74 myBinariesToProcess = null; | |
75 myBuild = null; | |
76 } | |
77 }); | |
78 } | |
79 | |
80 @Override | |
81 public void afterCollectingFiles(@NotNull List<ArtifactsCollection> artifacts) { | |
82 super.afterCollectingFiles(artifacts); | |
83 if(myBuild == null || mySymbolsToProcess == null || myBinariesToProcess == null) return; | |
84 if(myBuild.getBuildFeaturesOfType(SymbolsConstants.BUILD_FEATURE_TYPE).isEmpty()){ | |
85 LOG.debug(SymbolsConstants.BUILD_FEATURE_TYPE + " build feature disabled. No indexing performed."); | |
86 return; | |
87 } | |
88 LOG.debug(SymbolsConstants.BUILD_FEATURE_TYPE + " build feature enabled. Searching for symbol files."); | |
89 mySymbolsToProcess.addAll(getArtifactPathsByFileExtension(artifacts, PDB_FILE_EXTENSION)); | |
90 myBinariesToProcess.addAll(getArtifactPathsByFileExtension(artifacts, EXE_FILE_EXTENSION)); | |
91 myBinariesToProcess.addAll(getArtifactPathsByFileExtension(artifacts, DLL_FILE_EXTENSION)); | |
92 } | |
93 | |
94 private Collection<File> getArtifactPathsByFileExtension(List<ArtifactsCollection> artifactsCollections, String fileExtension){ | |
95 final Collection<File> result = new HashSet<File>(); | |
96 for(ArtifactsCollection artifactsCollection : artifactsCollections){ | |
97 if(artifactsCollection.isEmpty()) continue; | |
98 for (File artifact : artifactsCollection.getFilePathMap().keySet()){ | |
99 if(FileUtil.getExtension(artifact.getPath()).equalsIgnoreCase(fileExtension)) | |
100 result.add(artifact); | |
101 } | |
102 } | |
103 return result; | |
104 } | |
105 | |
106 private File dumpSymbolSignatures(Collection<File> files, File targetDir) throws IOException { | |
107 final File tempFile = FileUtil.createTempFile(targetDir, "symbol-signatures-", ".xml", false); | |
108 runTool(DUMP_SYMBOL_SIGN_CMD, files, tempFile); | |
109 return tempFile; | |
110 } | |
111 | |
112 private File dumpBinarySignatures(Collection<File> files, File targetDir) throws IOException { | |
113 final File tempFile = FileUtil.createTempFile(targetDir, "binary-signatures-", ".xml", false); | |
114 runTool(DUMP_BIN_SIGN_CMD, files, tempFile); | |
115 return tempFile; | |
116 } | |
117 | |
118 private void runTool(String cmd, Collection<File> files, File output){ | |
119 final GeneralCommandLine commandLine = new GeneralCommandLine(); | |
120 commandLine.setExePath(myNativeToolPath.getPath()); | |
121 commandLine.addParameter(cmd); | |
122 commandLine.addParameter(String.format("/o=\"%s\"", output.getPath())); | |
123 for(File file : files){ | |
124 commandLine.addParameter(file.getPath()); | |
125 } | |
126 final ExecResult execResult = SimpleCommandLineProcessRunner.runCommand(commandLine, null); | |
127 if (execResult.getExitCode() == 0) return; | |
128 LOG.warn(String.format("%s ends with non-zero exit code.", SYMBOLS_EXE)); | |
129 } | |
130 } |