-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactored artifact augmentation out * Added the ability to inject github client in augmenters to have count of github stars * The addgithubstars augmenter is now able to get stargazers on github, but how can we get them before a given date? * Seems like I'm starting to get some good github stars history * Seems like we *can* extract maven history with github stars * Allow mappings to be added * This file should NOT be commited * Changed Date to LocaDate, because it's better ? * Seems like it's working quite well for extracting today's numbers * Seems like I can also extract today's Python artifacts this way! * Fixing some small glitches * Some times, the repo doesn't exist * One more edge case! * Some times, there are no stargazers
- Loading branch information
Showing
41 changed files
with
2,502 additions
and
195,548 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,3 +132,6 @@ fabric.properties | |
**/.gitignore | ||
.idea/ | ||
.cache/ | ||
|
||
*/artifacts.json | ||
*/schema.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
model/src/main/java/org/ndx/aadarchi/technology/detector/augmenters/github/AddGitHub.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package org.ndx.aadarchi.technology.detector.augmenters.github; | ||
|
||
import java.time.LocalDate; | ||
import java.util.Date; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.TreeSet; | ||
import java.util.logging.Logger; | ||
|
||
import org.ndx.aadarchi.technology.detector.augmenters.Augmenter; | ||
import org.ndx.aadarchi.technology.detector.loader.ExtractionContext; | ||
import org.ndx.aadarchi.technology.detector.model.ArtifactDetails; | ||
import org.ndx.aadarchi.technology.detector.model.ArtifactDetailsBuilder; | ||
import org.ndx.aadarchi.technology.detector.model.GitHubDetailsBuilder; | ||
|
||
import io.github.emilyydev.asp.ProvidesService; | ||
|
||
@ProvidesService(Augmenter.class) | ||
public class AddGitHub implements Augmenter { | ||
private static final Logger logger = Logger.getLogger(AddGitHub.class.getName()); | ||
private final Set<String> alreadyLoggedProjects = new TreeSet<>(); | ||
public static final int ADD_GITHUB_OBJECT = 100; | ||
|
||
@Override | ||
public int order() { | ||
return ADD_GITHUB_OBJECT; | ||
} | ||
|
||
@Override | ||
public ArtifactDetails augment(ExtractionContext context, ArtifactDetails source, LocalDate date) { | ||
if(source.getGithubDetails()==null) { | ||
if(GitHubProjects.contains(source)) { | ||
return doAugment(context, source,GitHubProjects.getGitHubPath(source), date); | ||
} else if(source.getUrls()!=null && source.getUrls().containsKey("github.com")) { | ||
return doAugment(context, source, GitHubProjects.getGitHubPath(source.getUrls().get("github.com")), date); | ||
} else { | ||
if(!alreadyLoggedProjects.contains(source.getIdentifier())) { | ||
logger.warning(String.format("There doesn't seems to be any github repo for "+source.getIdentifier())); | ||
alreadyLoggedProjects.add(source.getIdentifier()); | ||
} | ||
} | ||
} | ||
return source; | ||
} | ||
|
||
private ArtifactDetails doAugment(ExtractionContext context, ArtifactDetails source, String path, LocalDate date) { | ||
ArtifactDetailsBuilder builder = ArtifactDetailsBuilder.toBuilder(source); | ||
return builder.githubDetails(GitHubDetailsBuilder.gitHubDetails() | ||
.stargazers(Optional.empty()) | ||
.path(path) | ||
.build()) | ||
.build(); | ||
} | ||
|
||
} |
140 changes: 140 additions & 0 deletions
140
...n/java/org/ndx/aadarchi/technology/detector/augmenters/github/AddGitHubStarsAtPeriod.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package org.ndx.aadarchi.technology.detector.augmenters.github; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.time.Duration; | ||
import java.time.LocalDate; | ||
import java.time.Period; | ||
import java.time.ZoneOffset; | ||
import java.util.Collections; | ||
import java.util.Date; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.StreamSupport; | ||
|
||
import org.kohsuke.github.GHFileNotFoundException; | ||
import org.kohsuke.github.GHRepository; | ||
import org.kohsuke.github.GHStargazer; | ||
import org.kohsuke.github.PagedIterable; | ||
import org.ndx.aadarchi.technology.detector.augmenters.Augmenter; | ||
import org.ndx.aadarchi.technology.detector.helper.FileHelper; | ||
import org.ndx.aadarchi.technology.detector.loader.ExtractionContext; | ||
import org.ndx.aadarchi.technology.detector.model.ArtifactDetails; | ||
import org.ndx.aadarchi.technology.detector.model.GitHubDetails; | ||
|
||
import com.fasterxml.jackson.core.type.TypeReference; | ||
|
||
import io.github.emilyydev.asp.ProvidesService; | ||
|
||
@ProvidesService(Augmenter.class) | ||
public class AddGitHubStarsAtPeriod implements Augmenter { | ||
private static final Logger logger = Logger.getLogger(AddGitHubStarsAtPeriod.class.getName()); | ||
|
||
@Override | ||
public int order() { | ||
return AddGitHub.ADD_GITHUB_OBJECT+1; | ||
} | ||
|
||
@Override | ||
public ArtifactDetails augment(ExtractionContext context, ArtifactDetails source, LocalDate date) { | ||
if(source.getGithubDetails()!=null) { | ||
return doAugment(context, source, date); | ||
} | ||
return source; | ||
} | ||
|
||
private ArtifactDetails doAugment(ExtractionContext context, ArtifactDetails source, LocalDate date) { | ||
GitHubDetails githubDetails = source.getGithubDetails(); | ||
if(githubDetails.getStargazers().isEmpty()) { | ||
// We have a special edge case to distinguish between | ||
// history rebuilding and standard data fetching. | ||
// When getting this month stargazers, it's way faster to ask | ||
// GitHub directly instead of getting the precise list of stargazers | ||
LocalDate now = LocalDate.now(); | ||
Period period = Period.between(date, now); | ||
if(period.toTotalMonths()>0) { | ||
extractStargazersHistory(context, source, date, githubDetails); | ||
} else { | ||
extractStargazersToday(context, source, githubDetails); | ||
} | ||
} | ||
return source; | ||
} | ||
|
||
private void extractStargazersToday(ExtractionContext context, ArtifactDetails source, GitHubDetails githubDetails) { | ||
try { | ||
GHRepository repository = context.getGithub().getRepository(source.getGithubDetails().getPath()); | ||
githubDetails.setStargazers(Optional.of(repository.getStargazersCount())); | ||
} catch (IOException e) { | ||
logger.log(Level.WARNING, String.format("Can't get stargazers count for artifact %s (supposedly at %s)", source.getCoordinates(), githubDetails.getPath()), e); | ||
} | ||
} | ||
|
||
private void extractStargazersHistory(ExtractionContext context, ArtifactDetails source, LocalDate date, | ||
GitHubDetails githubDetails) { | ||
Date old = Date.from(date.atStartOfDay(ZoneOffset.UTC).toInstant()); | ||
List<Stargazer> allStargazers = getAllStargazers(context, source, githubDetails); | ||
long numberOfStargazersBefore = allStargazers.stream() | ||
.filter(s -> s.getStarredAt().compareTo(old)<0) | ||
.count(); | ||
githubDetails.setStargazers(Optional.of((int) numberOfStargazersBefore)); | ||
} | ||
|
||
private List<Stargazer> getAllStargazers(ExtractionContext context, ArtifactDetails source, GitHubDetails details) { | ||
File cache = context.getCache() | ||
.resolve("github") | ||
.resolve(details.getPath()) | ||
.resolve("stargazers.json") | ||
.toFile(); | ||
cache.getParentFile().mkdirs(); | ||
if(!cache.exists() || cache.lastModified()<System.currentTimeMillis()-Duration.ofDays(7).toMillis()) { | ||
List<Stargazer> stargazers = doGetAllStargazers(context, details.getPath()); | ||
try { | ||
FileHelper.writeToFile(stargazers, cache); | ||
} catch (IOException e) { | ||
throw new RuntimeException("Can't write stargazers to "+cache.getAbsolutePath(), e); | ||
} | ||
} | ||
try { | ||
return FileHelper.readFromFile(cache, new TypeReference<List<Stargazer>>() {}); | ||
} catch (IOException e) { | ||
throw new RuntimeException("Can't read stargazers from "+cache.getAbsolutePath(), e); | ||
} | ||
} | ||
|
||
private List<Stargazer> doGetAllStargazers(ExtractionContext context, String githubRepositoryUrl) { | ||
try { | ||
logger.info("Fetching stargazers history of "+githubRepositoryUrl); | ||
GHRepository repository = context.getGithub().getRepository(githubRepositoryUrl); | ||
int total = repository.getStargazersCount(); | ||
PagedIterable<GHStargazer> stargazers = repository | ||
.listStargazers2() | ||
.withPageSize(100); | ||
AtomicInteger atomic = new AtomicInteger(0); | ||
List<Stargazer> allStargazers = StreamSupport.stream(stargazers.spliterator(), false) | ||
.peek(consumer -> { | ||
int current = atomic.incrementAndGet(); | ||
if(current%100==0) { | ||
logger.info(String.format("Fetched %d/%d stargazers of %s", | ||
current, total, githubRepositoryUrl)); | ||
} | ||
}) | ||
.map(s -> new Stargazer(s)) | ||
.sorted() | ||
.collect(Collectors.toList()); | ||
return allStargazers; | ||
} catch (GHFileNotFoundException e) { | ||
logger.log(Level.SEVERE, "Weirdly, repository "+githubRepositoryUrl+" doesn't seems to exist"); | ||
return Collections.emptyList(); | ||
} catch (IOException e) { | ||
throw new RuntimeException("TODO handle IOException", e); | ||
} finally { | ||
logger.info("Fetched stargazers history of "+githubRepositoryUrl); | ||
} | ||
} | ||
|
||
} |
59 changes: 59 additions & 0 deletions
59
.../src/main/java/org/ndx/aadarchi/technology/detector/augmenters/github/GitHubProjects.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package org.ndx.aadarchi.technology.detector.augmenters.github; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.Properties; | ||
import java.util.function.Function; | ||
|
||
import org.ndx.aadarchi.technology.detector.model.ArtifactDetails; | ||
|
||
public class GitHubProjects { | ||
public static final String GITHUB_REPOSITORIES = "github.repositories.properties"; | ||
|
||
private static final Properties githubProjects; | ||
|
||
static { | ||
githubProjects = new Properties(); | ||
if(GitHubProjects.class.getClassLoader().getResource(GITHUB_REPOSITORIES)!=null) { | ||
try(InputStream input = GitHubProjects.class.getClassLoader().getResourceAsStream(GITHUB_REPOSITORIES)) { | ||
githubProjects.load(input); | ||
} catch (IOException e) { | ||
throw new RuntimeException("Can't read "+GITHUB_REPOSITORIES, e); | ||
} | ||
} | ||
} | ||
|
||
public static Properties get() { | ||
return githubProjects; | ||
} | ||
|
||
public static String getGitHubPath(ArtifactDetails details) { | ||
for(Function<ArtifactDetails, String> extractor : ArtifactDetails.GITHUB_REPO_EXTRACTORS) { | ||
String key = extractor.apply(details); | ||
if(key!=null) | ||
return getGitHubPath(get().getProperty(key)); | ||
} | ||
return null; | ||
} | ||
|
||
public static String getGitHubPath(String githubRepositoryUrl) { | ||
String GITHUB = "github.com/"; | ||
String returned = githubRepositoryUrl.substring(githubRepositoryUrl.indexOf(GITHUB)+GITHUB.length()); | ||
String[] parts = returned.split("[/#]"); | ||
if(parts.length<=2) { | ||
return returned; | ||
} else { | ||
return parts[0]+"/"+parts[1]; | ||
} | ||
} | ||
|
||
public static boolean contains(ArtifactDetails source) { | ||
for(Function<ArtifactDetails, String> extractor : ArtifactDetails.GITHUB_REPO_EXTRACTORS) { | ||
String key = extractor.apply(source); | ||
if(key!=null && get().containsKey(key)) | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} |
Oops, something went wrong.