1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.plugins.changes.github;
20  
21  import java.io.IOException;
22  import java.net.MalformedURLException;
23  import java.net.URL;
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.List;
27  
28  import org.apache.maven.plugin.logging.Log;
29  import org.apache.maven.plugins.changes.issues.Issue;
30  import org.apache.maven.project.MavenProject;
31  import org.apache.maven.settings.Server;
32  import org.apache.maven.settings.Settings;
33  import org.apache.maven.settings.building.SettingsProblem;
34  import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
35  import org.apache.maven.settings.crypto.SettingsDecrypter;
36  import org.apache.maven.settings.crypto.SettingsDecryptionResult;
37  import org.kohsuke.github.GHIssue;
38  import org.kohsuke.github.GHIssueState;
39  import org.kohsuke.github.GHLabel;
40  import org.kohsuke.github.GitHubBuilder;
41  
42  
43  
44  
45  public class GitHubDownloader {
46  
47      
48  
49  
50      private GitHubBuilder client;
51  
52      
53  
54  
55      private boolean includeOpenIssues;
56  
57      
58  
59  
60      private boolean onlyMilestoneIssues;
61  
62      
63  
64  
65      private String githubOwner;
66  
67      
68  
69  
70      private String githubRepo;
71  
72      
73  
74  
75      private String githubIssueURL;
76  
77      public GitHubDownloader(MavenProject project, boolean includeOpenIssues, boolean onlyMilestoneIssues)
78              throws IOException {
79          this.includeOpenIssues = includeOpenIssues;
80          this.onlyMilestoneIssues = onlyMilestoneIssues;
81  
82          URL githubURL = new URL(project.getIssueManagement().getUrl());
83  
84          
85          
86          if (githubURL.getHost().equalsIgnoreCase("github.com")) {
87              this.client = new GitHubBuilder();
88          } else {
89              this.client = new GitHubBuilder()
90                      .withEndpoint(githubURL.getProtocol() + "://" + githubURL.getHost()
91                              + (githubURL.getPort() == -1 ? "" : ":" + githubURL.getPort()));
92          }
93  
94          this.githubIssueURL = project.getIssueManagement().getUrl();
95          if (!this.githubIssueURL.endsWith("/")) {
96              this.githubIssueURL = this.githubIssueURL + "/";
97          }
98  
99          String urlPath = githubURL.getPath();
100         if (urlPath.startsWith("/")) {
101             urlPath = urlPath.substring(1);
102         }
103 
104         if (urlPath.endsWith("/")) {
105             urlPath = urlPath.substring(0, urlPath.length() - 2);
106         }
107 
108         String[] urlPathParts = urlPath.split("/");
109 
110         if (urlPathParts.length != 3) {
111             throw new MalformedURLException(
112                     "GitHub issue management URL must look like, " + "[GITHUB_DOMAIN]/[OWNER]/[REPO]/issues");
113         }
114 
115         this.githubOwner = urlPathParts[0];
116         this.githubRepo = urlPathParts[1];
117     }
118 
119     protected Issue createIssue(GHIssue githubIssue) throws IOException {
120         Issue issue = new Issue();
121 
122         issue.setKey(String.valueOf(githubIssue.getNumber()));
123         issue.setId(String.valueOf(githubIssue.getNumber()));
124 
125         issue.setLink(this.githubIssueURL + githubIssue.getNumber());
126 
127         issue.setCreated(githubIssue.getCreatedAt());
128 
129         issue.setUpdated(githubIssue.getUpdatedAt());
130 
131         if (githubIssue.getAssignee() != null) {
132             if (githubIssue.getAssignee().getName() != null) {
133                 issue.setAssignee(githubIssue.getAssignee().getName());
134             } else {
135                 issue.setAssignee(githubIssue.getAssignee().getLogin());
136             }
137         }
138 
139         issue.setSummary(githubIssue.getTitle());
140 
141         if (githubIssue.getMilestone() != null) {
142             issue.addFixVersion(githubIssue.getMilestone().getTitle());
143         }
144 
145         issue.setReporter(githubIssue.getUser().getLogin());
146 
147         issue.setStatus(githubIssue.getState().name());
148 
149         final Collection<GHLabel> labels = githubIssue.getLabels();
150         if (labels != null && !labels.isEmpty()) {
151             issue.setType(labels.stream().findAny().get().getName());
152         }
153 
154         return issue;
155     }
156 
157     public List<Issue> getIssueList() throws IOException {
158         List<Issue> issueList = new ArrayList<>();
159 
160         if (includeOpenIssues) {
161             final List<GHIssue> openIssues =
162                     client.build().getRepository(githubOwner + "/" + githubRepo).getIssues(GHIssueState.OPEN);
163             for (final GHIssue issue : openIssues) {
164                 if (!onlyMilestoneIssues || issue.getMilestone() != null) {
165                     issueList.add(createIssue(issue));
166                 }
167             }
168         }
169 
170         final List<GHIssue> closedIssues =
171                 client.build().getRepository(githubOwner + "/" + githubRepo).getIssues(GHIssueState.CLOSED);
172 
173         for (final GHIssue issue : closedIssues) {
174             if (!onlyMilestoneIssues || issue.getMilestone() != null) {
175                 issueList.add(createIssue(issue));
176             }
177         }
178 
179         return issueList;
180     }
181 
182     public void configureAuthentication(
183             SettingsDecrypter decrypter, String githubAPIServerId, Settings settings, Log log) {
184         boolean configured = false;
185 
186         List<Server> servers = settings.getServers();
187 
188         for (Server server : servers) {
189             if (server.getId().equals(githubAPIServerId)) {
190                 SettingsDecryptionResult result = decrypter.decrypt(new DefaultSettingsDecryptionRequest(server));
191                 for (SettingsProblem problem : result.getProblems()) {
192                     log.error(problem.getMessage(), problem.getException());
193                 }
194                 server = result.getServer();
195                 String password = server.getPassword();
196                 client.withJwtToken(password);
197 
198                 configured = true;
199                 break;
200             }
201         }
202 
203         if (!configured) {
204             log.warn("Can't find server id [" + githubAPIServerId + "] configured in settings.xml");
205         }
206     }
207 }