Source code for citelang.main.packages.github

__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2022, Vanessa Sochat"
__license__ = "MPL 2.0"

# Custom package managers not in libraries IO

import os

import requests

import citelang.utils as utils
from citelang.logger import logger

from .base import PackageManager


[docs]def find_dependencies(repo): """ Given a repository root, look for dependency files. We could use the GraphQL library, but this REQUIRES a GitHub token, which is kind of annoying. For now we are trying to scrape them :) """ try: from bs4 import BeautifulSoup except ImportError: logger.exit( "You need beautiful soup in order to get GitHub dependencies. pip install bs4" ) url = "https://github.com/{}/network/dependencies".format(repo) repos = set() while url is not None: response = requests.get(url) if response.status_code != 200: logger.warning("Issue getting dependencies for %s" % repo) return [{"name": x} for x in sorted(list(repos))] soup = BeautifulSoup(response.content, "html.parser") for t in soup.findAll("div", {"class": "Box-row"}): repo = t.find("a", {"data-hovercard-type": "repository"}) if repo: repo = repo.text.replace(" ", "").strip() repos.add(repo) # Do we have pagination? pagination = soup.find("div", {"class": "paginate-container"}) url = None if pagination: pagination_a = pagination.find("a") if pagination_a: url = pagination_a["href"] # Ensure dependencies come with homepage return [ {"name": x, "homepage": "https://github.com/%s" % x} for x in sorted(list(repos)) ]
[docs]class GitHubManager(PackageManager): """ Packages from GitHub, either release, or branch. """ name = "github" apiroot = "https://api.github.com" homepage = "https://github.com" color = "#000000" default_language = None project_count = None default_versions = ["main", "master", "develop"]
[docs] def clone(self, name): """ Clone a repository and sniff for dependency files. """ return utils.clone(name)
[docs] def package(self, name, **kwargs): # Ensure name in right format if not name.count("/") == 1: logger.exit("Please provide a repository in the format <org>/<name") headers = { "Accept": "application/vnd.github.v3+json;application/vnd.github.antiope-preview+json;application/vnd.github.shadow-cat-preview+json" } token = os.environ.get("GITHUB_TOKEN") if token: headers["Authorization"] = "token %s" % token else: logger.warning("Your API requests will be limited without GITHUB_TOKEN") repo = self.get_or_fail(f"{self.apiroot}/repos/{name}", headers) # Try to provide a default version repo["default_version"] = repo["default_branch"] # Parse repos dependency page. This includes deps for CI too. repo["dependencies"] = find_dependencies(name) repo["name"] = repo["full_name"] # Get versions from releases API releases = self.get_or_fail( f"{self.apiroot}/repos/{name}/releases?per_page=100", headers ) repo["versions"] = [ {"published_at": x["published_at"], "number": x["tag_name"]} for x in releases ] if not repo["homepage"]: repo["homepage"] = repo["html_url"] return repo