Skip to content

Commit

Permalink
resolves netlify#510 add support for projects hosted on GitLab
Browse files Browse the repository at this point in the history
  • Loading branch information
mojavelinux committed Jun 9, 2019
1 parent 87ceb79 commit 8c79f1c
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 27 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"@octokit/rest": "^14.0.9",
"date-fns": "^1.29.0",
"dotenv": "^5.0.0",
"gitlab": "^5.0.1",
"gray-matter": "^3.1.1",
"js-yaml": "^3.11.0",
"marked": "^0.3.14",
Expand Down
50 changes: 33 additions & 17 deletions scripts/fetch-archive.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import path from 'path'
import fs from 'fs-extra'
import { map, find, fromPairs, mapValues } from 'lodash'
import { compact, map, find, fromPairs, mapValues } from 'lodash'
import fetch from 'node-fetch'
import { differenceInMinutes } from 'date-fns'
import Octokit from '@octokit/rest'
import { Gitlab } from 'gitlab'
import twitterFollowersCount from 'twitter-followers-count'

require('dotenv').config()

const GITHUB_TOKEN = process.env.STATICGEN_GITHUB_TOKEN
const GITLAB_TOKEN = process.env.STATICGEN_GITLAB_TOKEN
const TWITTER_CONSUMER_KEY = process.env.STATICGEN_TWITTER_CONSUMER_KEY
const TWITTER_CONSUMER_SECRET = process.env.STATICGEN_TWITTER_CONSUMER_SECRET
const TWITTER_ACCESS_TOKEN_KEY = process.env.STATICGEN_TWITTER_ACCESS_TOKEN_KEY
Expand All @@ -18,11 +20,13 @@ const LOCAL_ARCHIVE_PATH = `tmp/${ARCHIVE_FILENAME}`
const GIST_ARCHIVE_DESCRIPTION = 'STATICGEN.COM DATA ARCHIVE'

let octokit
let gitlab
let getTwitterFollowers

function authenticate () {
octokit = Octokit()
octokit.authenticate({ type: 'token', token: GITHUB_TOKEN })
gitlab = new Gitlab({ personaltoken: GITLAB_TOKEN })
getTwitterFollowers = twitterFollowersCount({
consumer_key: TWITTER_CONSUMER_KEY,
consumer_secret: TWITTER_CONSUMER_SECRET,
Expand All @@ -34,38 +38,50 @@ function authenticate () {
async function getProjectGitHubData (repo) {
const [owner, repoName] = repo.split('/')
const { data } = await octokit.repos.get({ owner, repo: repoName })
const { stargazers_count, forks_count, open_issues_count } = data
return { stars: stargazers_count, forks: forks_count, issues: open_issues_count }
const { stargazers_count, forks_count, open_issues_count, html_url } = data
return { stars: stargazers_count, forks: forks_count, issues: open_issues_count, repo: html_url }
}

async function getAllProjectGitHubData (repos) {
async function getProjectGitLabData (repo) {
const { id, star_count, forks_count, web_url } = await gitlab.Projects.show(repo)
const open_issues_count = (await gitlab.Issues.all({ projectId: id, state: 'opened' })).length
return { stars: star_count, forks: forks_count, issues: open_issues_count, repo: web_url }
}

async function getAllProjectRepoData (repos) {
const data = []
// eslint-disable-next-line no-restricted-syntax
for (const repo of repos) {
for (const repoWithHost of repos) {
const [repoHost, repo] = repoWithHost.split(':')
// eslint-disable-next-line no-await-in-loop
await new Promise(res => setTimeout(res, 100))
try {
// eslint-disable-next-line no-await-in-loop
const repoData = await getProjectGitHubData(repo)
data.push([repo, repoData])
if (repoHost === 'gitlab') {
// eslint-disable-next-line no-await-in-loop
const repoData = await getProjectGitLabData(repo)
data.push([repoWithHost, repoData])
} else {
// eslint-disable-next-line no-await-in-loop
const repoData = await getProjectGitHubData(repo)
data.push([repoWithHost, repoData])
}
} catch (err) {
console.error(`Could not load repository "${repo}". Please make sure it still exists.`)
console.error(`Could not load repository "${repo}" from ${repoHost}. Please make sure it still exists.`)
}
}
return fromPairs(data)
}

async function getAllProjectData (projects) {
const timestamp = Date.now()
const twitterScreenNames = map(projects, 'twitter').filter(val => val)
const twitterFollowers = twitterScreenNames.length &&
await getTwitterFollowers(twitterScreenNames)
const gitHubRepos = map(projects, 'repo').filter(val => val)
const gitHubReposData = await getAllProjectGitHubData(gitHubRepos)
const data = projects.reduce((obj, { key, repo, twitter }) => {
const twitterScreenNames = compact(map(projects, 'twitter'))
const twitterFollowers = twitterScreenNames.length && await getTwitterFollowers(twitterScreenNames)
const repos = compact(map(projects, val => val.repo ? [val.repohost || 'github', val.repo].join(':') : undefined))
const reposData = await getAllProjectRepoData(repos)
const data = projects.reduce((obj, { key, repo, repohost, twitter }) => {
const twitterData = twitter ? { followers: twitterFollowers[twitter] } : {}
const gitHubData = repo ? { ...(gitHubReposData[repo]) } : {}
return { ...obj, [key]: [{ timestamp, ...twitterData, ...gitHubData }] }
const repoData = repo ? { ...(reposData[[repohost || 'github', repo].join(':')]) } : {}
return { ...obj, [key]: [{ timestamp, ...twitterData, ...repoData }] }
}, {})
return { timestamp, data }
}
Expand Down
2 changes: 1 addition & 1 deletion site.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ navLinks:
- { url: https://jamstack.org, text: About JAMstack }
- { url: https://headlesscms.org, text: Need a Static CMS? }
sorts:
- { field: "stars", label: "GitHub stars", reverse: true }
- { field: "stars", label: "Repo stars", reverse: true }
- { field: "followers", label: "Twitter followers", reverse: true }
- { field: "title", label: "Title" }
filters:
Expand Down
2 changes: 1 addition & 1 deletion src/Home/DeployButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import netlifyLogo from 'Images/netlify-logo.svg'
const DeployButton = styled(({ repo, className }) => (
<a
className={className}
href={`https://app.netlify.com/start/deploy?repository=https://github.com/${repo}`}
href={`https://app.netlify.com/start/deploy?repository=${repo}`}
>
<img alt="" src={netlifyLogo} /> Deploy to Netlify
</a>
Expand Down
6 changes: 3 additions & 3 deletions src/Home/Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const Project = ({
<OpenSourceStat
key="stars"
Icon={() => <Octicon name="star" zoom="100%" />}
label="GitHub stars"
label="Repo stars"
value={stars}
change={stars - starsPrevious}
indicateColor
Expand All @@ -49,15 +49,15 @@ const Project = ({
<OpenSourceStat
key="issues"
Icon={() => <Octicon name="issue-opened" zoom="100%" />}
label="GitHub open issues"
label="Open issues"
value={issues}
change={issues - issuesPrevious}
dataAgeInDays={dataAgeInDays}
/>,
<OpenSourceStat
key="forks"
Icon={() => <Octicon name="repo-forked" zoom="100%" />}
label="GitHub forks"
label="Repo forks"
value={forks}
change={forks - forksPrevious}
indicateColor
Expand Down
4 changes: 2 additions & 2 deletions src/Project/Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ class Project extends React.Component {
</DetailLink>
}
{repo &&
<DetailLink href={`https://github.com/${repo}`}>
<EntypoIcon Icon={EntypoGithub} /> https://github.com/{repo} ({stars})
<DetailLink href={repo}>
<EntypoIcon Icon={EntypoGithub} /> {repo} ({stars})
</DetailLink>
}
</div>
Expand Down
19 changes: 16 additions & 3 deletions static.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,31 @@ function processMarkdown (markdown, key) {
function mapProjectFrontMatter ({
title,
repo,
repohost,
homepage,
description,
startertemplaterepo,
content,
twitter,
}) {
const repoHost = repohost || 'github'
let starterTemplateRepo = startertemplaterepo
if (starterTemplateRepo && !starterTemplateRepo.includes(':')) {
if (repoHost === 'github') {
starterTemplateRepo = `https://github.com/${starterTemplateRepo}`
} else if (repoHost === 'gitlab') {
starterTemplateRepo = `https://gitlab.com/${starterTemplateRepo}`
}
}
return {
title,
slug: toSlug(title),
repo,
repoHost,
homepage,
twitter,
description,
starterTemplateRepo: startertemplaterepo,
starterTemplateRepo,
content,
}
}
Expand All @@ -56,15 +67,15 @@ function extractRelevantProjectData (data) {
const oldestTimestamp = dateFns.min(...timestamps).getTime()
const dataAgeInDays = dateFns.differenceInDays(Date.now(), oldestTimestamp)
const {
followers, forks, stars, issues,
followers, forks, stars, issues, repo
} = find(project, { timestamp: newestTimestamp }) || {}
const {
forks: forksPrevious,
stars: starsPrevious,
issues: issuesPrevious,
followers: followersPrevious,
} = find(project, { timestamp: oldestTimestamp }) || {}
return {
const relevantData = {
followers,
forks,
stars,
Expand All @@ -75,6 +86,8 @@ function extractRelevantProjectData (data) {
followersPrevious,
dataAgeInDays,
}
if (repo) relevantData.repo = repo
return relevantData
})
}

Expand Down

0 comments on commit 8c79f1c

Please sign in to comment.