View Javadoc

1   /**
2    * Copyright (C) 2012 White Source Ltd.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.whitesource.teamcity.agent;
17  
18  import jetbrains.buildServer.agent.AgentRunningBuild;
19  import jetbrains.buildServer.agent.BuildRunnerContext;
20  import jetbrains.buildServer.log.Loggers;
21  import jetbrains.buildServer.util.FileUtil;
22  import jetbrains.buildServer.util.StringUtil;
23  import org.whitesource.agent.api.ChecksumUtils;
24  import org.whitesource.agent.api.model.AgentProjectInfo;
25  import org.whitesource.agent.api.model.Coordinates;
26  import org.whitesource.agent.api.model.DependencyInfo;
27  import org.whitesource.teamcity.common.WssUtils;
28  
29  import java.io.File;
30  import java.io.IOException;
31  import java.util.ArrayList;
32  import java.util.Collection;
33  import java.util.List;
34  import java.util.regex.Pattern;
35  
36  /**
37   * Concrete implementation for generic job types.
38   * Based on user entered locations of open source libraries.
39   *
40   * @author Edo.Shor
41   */
42  public class GenericOssInfoExtractor extends BaseOssInfoExtractor {
43  
44      /* --- Static members --- */
45  
46      private static final String LOG_COMPONENT = "GenericExtractor";
47  
48      /* --- Members --- */
49  
50      protected List<Pattern> includePatterns;
51  
52      protected List<Pattern> excludePatterns;
53  
54      /* --- Constructors --- */
55  
56      /**
57       * Constructor
58       *
59       * @param runner
60       */
61      public GenericOssInfoExtractor(BuildRunnerContext runner) {
62          super(runner);
63  
64          includePatterns = new ArrayList<Pattern>();
65          for (String pattern : includes) {
66              includePatterns.add(Pattern.compile(FileUtil.convertAntToRegexp(pattern)));
67          }
68  
69          excludePatterns = new ArrayList<Pattern>();
70          for (String pattern : excludes) {
71              excludePatterns.add(Pattern.compile(FileUtil.convertAntToRegexp(pattern)));
72          }
73  
74      }
75  
76      /* --- Concrete implementation methods --- */
77  
78      @Override
79      public Collection<AgentProjectInfo> extract() {
80          Loggers.AGENT.info(WssUtils.logMsg(LOG_COMPONENT, "Collection started"));
81  
82          final AgentRunningBuild build = runner.getBuild();
83  
84          // we send something anyhow, even when no OSS found.
85          Collection<AgentProjectInfo> projectInfos = new ArrayList<AgentProjectInfo>();
86          AgentProjectInfo projectInfo = new AgentProjectInfo();
87          projectInfos.add(projectInfo);
88  
89          projectInfo.setCoordinates(new Coordinates(null, build.getProjectName(), null));
90          projectInfo.setProjectToken(projectToken);
91  
92          if (includePatterns.isEmpty()) {
93              Loggers.AGENT.warn(WssUtils.logMsg(LOG_COMPONENT, "No include patterns defined. Skipping."));
94              build.getBuildLogger().warning("No include patterns defined. Can't look for open source information.");
95          } else {
96              build.getBuildLogger().message("Including files matching:");
97              build.getBuildLogger().message(StringUtil.join(includes,"\n"));
98              if (excludes.isEmpty()) {
99                  build.getBuildLogger().message("Excluding none.");
100             } else {
101                 build.getBuildLogger().message("Excluding files matching:");
102                 build.getBuildLogger().message(StringUtil.join(excludes,"\n"));
103             }
104 
105             extractOssInfo(build.getCheckoutDirectory(), projectInfo.getDependencies());
106         }
107 
108         return projectInfos;
109     }
110 
111     /* --- Private methods --- */
112 
113     private void extractOssInfo(final File root, final Collection<DependencyInfo> dependencyInfos) {
114         extractOssInfo(root, root, dependencyInfos);
115     }
116 
117     private void extractOssInfo(final File absoluteRoot, final File root, final Collection<DependencyInfo> dependencyInfos) {
118         final File[] files = root.listFiles();
119         if (files == null){
120             return;
121         }
122 
123         for (File file : files) {
124             if (file.isFile()) {
125                 final String path = FileUtil.toSystemIndependentName(FileUtil.getRelativePath(absoluteRoot, file));
126 
127                 boolean process = matchAny(path, includePatterns);
128                 if (process) {
129                     process = !matchAny(path, excludePatterns);
130                 }
131 
132                 if (process) {
133                     dependencyInfos.add(extractDepependencyInfo(file));
134                 }
135             } else {
136                 extractOssInfo(absoluteRoot, file, dependencyInfos);
137             }
138         }
139     }
140 
141     private boolean matchAny(String value, List<Pattern> patterns) {
142         boolean match = false;
143 
144         for (Pattern pattern : patterns) {
145             if (pattern.matcher(value).matches()) {
146                 match = true;
147                 break;
148             }
149         }
150 
151         return match;
152     }
153 
154     private DependencyInfo extractDepependencyInfo(File file) {
155         DependencyInfo info = new DependencyInfo();
156 
157         info.setSystemPath(file.getAbsolutePath());
158         info.setArtifactId(file.getName());
159 
160         try {
161             info.setSha1(ChecksumUtils.calculateSHA1(file));
162         } catch (IOException e) {
163             String msg = "Error calculating SHA-1 for " + file.getAbsolutePath();
164             Loggers.AGENT.warn(WssUtils.logMsg(LOG_COMPONENT, msg));
165             runner.getBuild().getBuildLogger().message(msg);
166         }
167 
168         return info;
169     }
170 
171 }