(&self)
| 243 | } |
| 244 | |
| 245 | pub fn stats(&self) -> Result<RepoStats> { |
| 246 | log::info!("computing stats for view {:?}", self); |
| 247 | let tree = self.repo.commit(self.commit)?.tree()?; |
| 248 | |
| 249 | let mut topic_count = 0; |
| 250 | let mut link_count = 0; |
| 251 | |
| 252 | fn has_subsequence(haystack: &[u8], needle: &[u8]) -> bool { |
| 253 | haystack |
| 254 | .windows(needle.len()) |
| 255 | .any(|window| window == needle) |
| 256 | } |
| 257 | |
| 258 | tree.walk(git2::TreeWalkMode::PreOrder, |_root, entry| { |
| 259 | if let Some(name) = entry.name() { |
| 260 | if name != "object.yaml" { |
| 261 | return git2::TreeWalkResult::Ok; |
| 262 | } |
| 263 | |
| 264 | let oid = entry.id(); |
| 265 | |
| 266 | match self.repo.inner.find_blob(oid) { |
| 267 | Ok(blob) => { |
| 268 | let haystack = blob.content(); |
| 269 | if has_subsequence(haystack, b"kind: RepoTopic\n") { |
| 270 | topic_count += 1; |
| 271 | } else if has_subsequence(haystack, b"kind: RepoLink\n") { |
| 272 | link_count += 1; |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | Err(err) => { |
| 277 | log::error!("failed to convert to string: {}", err); |
| 278 | } |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | git2::TreeWalkResult::Ok |
| 283 | })?; |
| 284 | |
| 285 | Ok(RepoStats { |
| 286 | computing: false, |
| 287 | link_count: Some(link_count), |
| 288 | topic_count: Some(topic_count), |
| 289 | }) |
| 290 | } |
| 291 | |
| 292 | pub fn topic(&self, id: &ExternalId) -> Result<Option<RepoTopic>> { |
| 293 | let topic = match self.find_blob(id)? { |
no test coverage detected