mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-15 06:35:20 -07:00
Fetch formula status for homebrew
This commit is contained in:
parent
6338bff01c
commit
ec7a4eebff
7 changed files with 273 additions and 20 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -85,5 +85,6 @@ dist
|
|||
/static/app-list.json
|
||||
/README-temp.md
|
||||
/static/game-list.json
|
||||
/static/homebrew-list.json
|
||||
.DS_Store
|
||||
/commits-data.json
|
||||
|
|
|
|||
174
helpers/build-homebrew-list.js
Normal file
174
helpers/build-homebrew-list.js
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
|
||||
// import { promises as fs } from 'fs'
|
||||
// import MarkdownIt from 'markdown-it'
|
||||
import slugify from 'slugify'
|
||||
import axios from 'axios'
|
||||
|
||||
// import statuses from './statuses'
|
||||
// import parseGithubDate from './parse-github-date'
|
||||
|
||||
const marked = require('marked')
|
||||
const HTMLParser = require(`node-html-parser`)
|
||||
|
||||
|
||||
|
||||
const statusesTranslations = {
|
||||
|
||||
// brew install -s succeeds on Apple Silicon. The software works well enough natively.
|
||||
'🥇': 'native',
|
||||
|
||||
// The formula has been updated with depends_on :arch => [:x86_64, :build]. The software works well enough on Rosetta.
|
||||
'🥈': 'rosetta',
|
||||
|
||||
// The formula has known issues on macOS 11, though most features work. The issues are described in the Comments field.
|
||||
'🥉': 'rosetta',
|
||||
|
||||
// The formula has been updated with depends_on :arch => :x86_64. The software has been deemed to work on Intel only (for now).
|
||||
'🚫': 'no',
|
||||
|
||||
// The formula has been found to need more analysis/work.
|
||||
'⚠️': 'no',
|
||||
|
||||
}
|
||||
|
||||
const statusesMessages = {
|
||||
'🥇': '✅ Yes, Full Native Apple Silicon Support',
|
||||
'🥈': '✳️ Yes, works via Rosetta 2',
|
||||
'🥉': '⏹ Known issues on macOS 11, though most features work',
|
||||
'⚠️': '⏹ No, not yet, support is still in progress',
|
||||
'🚫': '🚫 No, not yet supported only works on Intel-based Macs'
|
||||
}
|
||||
|
||||
function getStatusText(formula) {
|
||||
// Match status to Sheet Status
|
||||
return statusesMessages[formula.status]
|
||||
}
|
||||
|
||||
function parseStatus(formulae) {
|
||||
// Match status to Sheet Status
|
||||
return statusesTranslations[formulae.status]
|
||||
}
|
||||
|
||||
|
||||
export default async function () {
|
||||
|
||||
// Fetch Homebrew
|
||||
const response = await axios.get(process.env.HOMEBREW_SOURCE)
|
||||
|
||||
// Extract commit from response data
|
||||
const issueMarkdown = response.data.data.repository.issue.body
|
||||
|
||||
// Parse markdown
|
||||
const issueHTML = marked(issueMarkdown)
|
||||
|
||||
// Parse Markdown HTML into a dom
|
||||
const dom = HTMLParser.parse(issueHTML)
|
||||
|
||||
|
||||
// Map table Headings
|
||||
// [ 'Formula', 'Works1on 11.0', 'Comments' ]
|
||||
// const tableHeadings = dom.querySelectorAll('thead th').map(th => th.rawText)
|
||||
|
||||
const headings = [
|
||||
'fullName',
|
||||
'status',
|
||||
'comments'
|
||||
]
|
||||
|
||||
// Map Formulae List within table
|
||||
const tableRows = dom.querySelectorAll('table tr')
|
||||
|
||||
// Remove the first row (Headings)
|
||||
tableRows.shift()
|
||||
|
||||
const tableRowData = tableRows.map( tr => {
|
||||
|
||||
// Map Table Cells
|
||||
|
||||
const cellsData = tr.querySelectorAll('td').map((td, i) => {
|
||||
|
||||
const column = headings[i]
|
||||
|
||||
if (td.childNodes.length === 0) return ''
|
||||
|
||||
if (column === 'comments') return td.innerHTML
|
||||
|
||||
return td.rawText
|
||||
})
|
||||
|
||||
const formulaeRow = Object.fromEntries(cellsData.map( (cellData, i) => {
|
||||
return [ headings[i], cellData ]
|
||||
}))
|
||||
|
||||
formulaeRow.name = formulaeRow.fullName.split(' ')[0]
|
||||
|
||||
formulaeRow.links = tr.querySelectorAll('a').map( a => {
|
||||
const href = a.getAttribute('href')
|
||||
return {
|
||||
href,
|
||||
label: a.rawText,
|
||||
// a
|
||||
}
|
||||
})
|
||||
|
||||
// if (formulaeRow.links.length !== 0) console.log('formulaeRow', formulaeRow.links)
|
||||
|
||||
return formulaeRow
|
||||
})
|
||||
|
||||
// console.log('dom', dom.length)
|
||||
// console.log('issueHTML', issueHTML)
|
||||
// console.log('formulaeWithStatus', formulaeWithStatus)
|
||||
|
||||
|
||||
const formulaeList = []
|
||||
|
||||
|
||||
for (const formulae of tableRowData) {
|
||||
|
||||
// If this formulae status is empty
|
||||
// then skip this formulae
|
||||
if (formulae.status.length === 0) continue
|
||||
|
||||
// If this formulae emoji status is not in statusesTranslations
|
||||
// then skip this formulae
|
||||
if (!statusesTranslations.hasOwnProperty(formulae.status)) continue
|
||||
|
||||
// Generate slug
|
||||
const slug = formulae.name
|
||||
|
||||
// slugify(formulae.name, {
|
||||
// lower: true,
|
||||
// strict: true
|
||||
// })
|
||||
|
||||
formulaeList.push({
|
||||
name: formulae.name,
|
||||
status: parseStatus(formulae),
|
||||
url: `https://formulae.brew.sh/formula/${formulae.name}`,
|
||||
text: getStatusText(formulae),
|
||||
slug,
|
||||
endpoint: `/formula/${slug}`,
|
||||
section: {
|
||||
label: 'Homebrew',
|
||||
slug: 'homebrew'
|
||||
},
|
||||
content: formulae.comments,
|
||||
relatedLinks: [
|
||||
{
|
||||
href: `https://formulae.brew.sh/formula/${formulae.name}`,
|
||||
label: formulae.name,
|
||||
// a
|
||||
},
|
||||
...formulae.links
|
||||
],
|
||||
// reports: [
|
||||
// formulae
|
||||
// ]
|
||||
})
|
||||
}
|
||||
|
||||
// console.log('formulaeList', formulaeList)
|
||||
|
||||
return formulaeList
|
||||
}
|
||||
12
helpers/get-list.js
Normal file
12
helpers/get-list.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import appList from '~/static/app-list.json'
|
||||
import gameList from '~/static/game-list.json'
|
||||
import homebrewList from '~/static/homebrew-list.json'
|
||||
|
||||
import { byTimeThenNull } from '~/helpers/sort-list.js'
|
||||
|
||||
|
||||
export const allList = [
|
||||
...appList.sort(byTimeThenNull),
|
||||
...homebrewList,
|
||||
...gameList,
|
||||
]
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
// import path from 'path'
|
||||
|
||||
import pkg from './package'
|
||||
import buildAppList from './helpers/build-app-list.js'
|
||||
import buildGamesList from './helpers/build-game-list.js'
|
||||
import buildHomebrewList from './helpers/build-homebrew-list.js'
|
||||
|
||||
|
||||
const listsOptions = [
|
||||
|
|
@ -14,6 +15,10 @@ const listsOptions = [
|
|||
{
|
||||
buildMethod: buildGamesList,
|
||||
path: '/static/game-list.json',
|
||||
},
|
||||
{
|
||||
buildMethod: buildHomebrewList,
|
||||
path: '/static/homebrew-list.json',
|
||||
}
|
||||
]
|
||||
|
||||
|
|
@ -91,21 +96,12 @@ export default {
|
|||
.then(( lists ) => {
|
||||
// console.log('appList', appList)
|
||||
|
||||
// const appRoutes = appList.map(app => ({
|
||||
// route: '/app/' + app.slug,
|
||||
// // payload: appList
|
||||
// }))
|
||||
|
||||
// const gameRoutes = gameList.map(game => ({
|
||||
// route: '/game/' + game.slug,
|
||||
// // payload: appList
|
||||
// }))
|
||||
|
||||
const sectionList = []
|
||||
|
||||
const [
|
||||
appRoutes,
|
||||
gameRoutes
|
||||
gameRoutes,
|
||||
homebrewRoutes
|
||||
] = lists.map((list, listI) => {
|
||||
return list.map( app => {
|
||||
// Find and store all sections
|
||||
|
|
@ -117,6 +113,8 @@ export default {
|
|||
})
|
||||
})
|
||||
|
||||
// console.log('homebrewRoutes', homebrewRoutes)
|
||||
|
||||
const sectionRoutes = sectionList.map(slug => ({
|
||||
route: '/kind/' + slug,
|
||||
// payload: appList
|
||||
|
|
@ -125,6 +123,7 @@ export default {
|
|||
return [
|
||||
...appRoutes,
|
||||
...gameRoutes,
|
||||
...homebrewRoutes,
|
||||
...sectionRoutes
|
||||
]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -38,21 +38,16 @@
|
|||
import Search from '~/components/search.vue'
|
||||
import LinkButton from '~/components/link-button.vue'
|
||||
|
||||
import { byTimeThenNull } from '~/helpers/sort-list.js'
|
||||
|
||||
// import appList from '~/static/app-list.json'
|
||||
// import gamelist from '~/static/game-list.json'
|
||||
|
||||
export default {
|
||||
async asyncData () {
|
||||
|
||||
const { default: appList } = await import('~/static/app-list.json')
|
||||
const { default: gamelist } = await import('~/static/game-list.json')
|
||||
// const { default: appList } = await import('~/static/app-list.json')
|
||||
// const { default: gamelist } = await import('~/static/game-list.json')
|
||||
|
||||
const allList = [
|
||||
...appList.sort(byTimeThenNull),
|
||||
...gamelist,
|
||||
]
|
||||
const { allList } = await import('~/helpers/get-list.js')
|
||||
|
||||
const sectionList = {}
|
||||
|
||||
|
|
|
|||
70
pages/formula/_slug.vue
Normal file
70
pages/formula/_slug.vue
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<template>
|
||||
<section class="container py-32">
|
||||
<div class="flex flex-col items-center text-center">
|
||||
<h1 class="title text-sm md:text-2xl font-semibold">
|
||||
Does <code>{{ app.name }}</code> work on Apple Silicon?
|
||||
</h1>
|
||||
<h2 class="subtitle text-2xl md:text-5xl font-bold py-6">
|
||||
{{ app.text }}
|
||||
</h2>
|
||||
|
||||
<small class="data-credit text-sm opacity-75 text-center mb-4">
|
||||
<span>According to Github</span>
|
||||
</small>
|
||||
|
||||
<div
|
||||
class="comments text-sm mb-8"
|
||||
v-html="app.content"
|
||||
/>
|
||||
|
||||
<div class="links space-y-6 sm:space-x-6 mb-8">
|
||||
<LinkButton
|
||||
v-for="(link, i) in app.relatedLinks"
|
||||
:key="i"
|
||||
:href="link.href"
|
||||
target="_blank"
|
||||
class=""
|
||||
>{{ (i === 0) ? 'View' : link.label }}</LinkButton>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LinkButton from '~/components/link-button.vue'
|
||||
import EmailSubscribe from '~/components/email-subscribe.vue'
|
||||
import ThomasCredit from '~/components/thomas-credit.vue'
|
||||
|
||||
import homebrewList from '~/static/homebrew-list.json'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LinkButton,
|
||||
EmailSubscribe,
|
||||
ThomasCredit
|
||||
},
|
||||
async asyncData ({ params: { slug } }) {
|
||||
|
||||
return {
|
||||
slug,
|
||||
app: homebrewList.find(app => (app.slug === slug))
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: `Does ${this.app.name} work on Apple Silicon?`,
|
||||
// meta: [
|
||||
// // hid is used as unique identifier. Do not use `vmid` for it as it will not work
|
||||
// {
|
||||
// hid: 'description',
|
||||
// name: 'description',
|
||||
// content: 'My custom description'
|
||||
// }
|
||||
// ]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -45,9 +45,11 @@ import { byTimeThenNull } from '~/helpers/sort-list.js'
|
|||
|
||||
import appList from '~/static/app-list.json'
|
||||
import gamelist from '~/static/game-list.json'
|
||||
import homebrewList from '~/static/homebrew-list.json'
|
||||
|
||||
const allList = [
|
||||
...appList.sort(byTimeThenNull),
|
||||
...homebrewList,
|
||||
...gamelist,
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue