2022-01-20 17:04:41 +01:00
#!/usr/bin/env python3
2020-05-01 19:25:17 +02:00
# License: MIT
# Copyright (C) Google
# Author: Vladimit 'phcoder' Serbinenko
import os
import csv
2022-01-20 17:04:41 +01:00
import requests
hostname = ' git.libretro.com '
namespace = ' libretro '
2020-05-01 19:25:17 +02:00
MISSING = ' missing '
OK = ' OK '
2022-01-20 17:04:41 +01:00
BROKEN = ' broken '
2020-05-01 19:25:17 +02:00
coremap = { }
allcores = set ( )
allplatformset = set ( )
corestatus = { }
corereason = { }
2022-01-20 17:04:41 +01:00
SUBCORE_SUFFIXES = [
" plus " ,
# bsnes
" accuracy " , " balanced " ,
# Beetle PSX
" hw " ,
# Quake
" rogue " , " xatrix " , " zaero " ,
# VICE
" xpet " , " xplus4 " , " xscpu64 " , " xvic " , " x128 " , " x64sc " , " xcbm2 " , " xcbm5x0 " ,
# Boom3
" xp " ,
# MAME
" cdi2015 "
]
2020-05-01 19:25:17 +02:00
GFX_FEATS = [ ' gfxaccel ' , ' gl1 ' , ' gl2 ' , ' gl3 ' , ' gles2 ' , ' gles3 ' ]
2022-01-20 17:04:41 +01:00
CPU_FEATS = [ ' x86_any ' , ' libco ' , ' cpu64 ' , ' threads ' , ' thread-local ' , ' jit ' , ' little_endian ' ]
2020-05-01 19:25:17 +02:00
PERIPHERAL_FEATS = [ ' cdrom ' , ' usb ' ]
2022-04-04 17:35:11 +02:00
LANG_FEATS = [ ' c++14 ' , ' c++11 ' ]
MISC_FEATS = [ ' physfs ' , ' jvm ' ]
2022-01-20 17:04:41 +01:00
ALL_FEATS = GFX_FEATS + CPU_FEATS + PERIPHERAL_FEATS + MISC_FEATS + LANG_FEATS
DESKTOP_COMMON = list ( set ( ALL_FEATS ) - set ( [ ' gles2 ' , ' gles3 ' , ' cpu64 ' , ' x86_any ' , ' little_endian ' ] ) )
DESKTOP_X64 = DESKTOP_COMMON + [ ' x86_any ' , ' cpu64 ' , ' little_endian ' ]
DESKTOP_X86 = DESKTOP_COMMON + [ ' x86_any ' , ' little_endian ' ]
2022-04-04 17:35:11 +02:00
DESKTOP_X64_NO_CXX11 = list ( set ( DESKTOP_X64 ) - set ( [ ' c++14 ' , ' c++11 ' ] ) )
DESKTOP_X86_NO_CXX11 = list ( set ( DESKTOP_X86 ) - set ( [ ' c++14 ' , ' c++11 ' ] ) )
2022-01-20 17:04:41 +01:00
DESKTOP_ARM32LE = DESKTOP_COMMON + [ ' little_endian ' ]
DESKTOP_PPC = DESKTOP_COMMON
2022-04-04 17:35:11 +02:00
UWP = [ ' gfxaccel ' , ' gles2 ' , ' threads ' , ' thread-local ' , ' libco ' ] + [ ' cdrom ' , ' usb ' , ' physfs ' , ' c++14 ' , ' c++11 ' , ' jvm ' ] # unsure about second part
2022-01-20 17:04:41 +01:00
MOBILE_LE = [ ' gfxaccel ' , ' gles2 ' , ' gles3 ' , ' threads ' , ' libco ' , ' little_endian ' ]
2022-04-04 17:35:11 +02:00
ANDROID = MOBILE_LE + [ ' jit ' , ' physfs ' , ' thread-local ' , ' c++14 ' , ' c++11 ' , ' jvm ' ]
2020-05-01 19:25:17 +02:00
features_platforms = {
# Misc
2022-04-04 17:35:11 +02:00
' emscripten ' : [ ' gfxaccel ' , ' gles2 ' , ' little_endian ' , ' physfs ' , ' c++14 ' , ' c++11 ' ] ,
2020-05-01 19:25:17 +02:00
# consoles
2022-04-04 17:35:11 +02:00
' ctr ' : [ ' threads ' , ' thread-local ' , ' libco ' , ' jit ' , ' little_endian ' , ' c++14 ' , ' c++11 ' ] ,
' psl1ght ' : [ ' cpu64 ' ] + [ ' libco ' , ' cdrom ' , ' usb ' , ' jit ' , ' c++14 ' , ' c++11 ' ] , # unsure about second part
' ngc ' : [ ' threads ' , ' thread-local ' , ' libco ' ] + [ ' cdrom ' , ' jit ' , ' c++14 ' , ' c++11 ' ] , # unsure about second part
' wii ' : [ ' threads ' , ' thread-local ' , ' libco ' ] + [ ' cdrom ' , ' usb ' , ' jit ' , ' c++14 ' , ' c++11 ' ] , # unsure about second part
' ps2 ' : [ ' little_endian ' ] + [ ' libco ' , ' cpu64 ' , ' threads ' , ' thread-local ' , ' cdrom ' , ' usb ' , ' jit ' , ' c++14 ' , ' c++11 ' ] , # unsure about second part
' ps3 ' : [ ' threads ' , ' thread-local ' , ' cpu64 ' ] + [ ' libco ' , ' cdrom ' , ' usb ' , ' jit ' , ' c++14 ' , ' c++11 ' ] , # unsure about second part
' psp ' : [ ' libco ' , ' threads ' , ' thread-local ' , ' little_endian ' ] + [ ' jit ' , ' c++14 ' , ' c++11 ' ] , # unsure about second part
' libnx-aarch64 ' : [ ' gfxaccel ' , ' gl1 ' , ' gl2 ' , ' gl3 ' , ' libco ' , ' cpu64 ' , ' threads ' , ' thread-local ' , ' jit ' , ' little_endian ' ] + [ ' usb ' , ' c++14 ' , ' c++11 ' ] , # unsure about second part
' wiiu ' : [ ' libco ' ] + [ ' cdrom ' , ' usb ' , ' jit ' , ' c++14 ' , ' c++11 ' ] + [ ' threads ' ] , # unsure about second part. Threads are present in OS but not in rthreads yet
' vita ' : [ ' gfxaccel ' , ' gl1 ' , ' gl2 ' , ' threads ' , ' thread-local ' , ' libco ' , ' jit ' , ' little_endian ' , ' c++14 ' , ' c++11 ' ] , # 'gl3', 'gles2', 'gles3'?
2020-05-01 19:25:17 +02:00
# UWP
2022-01-20 17:04:41 +01:00
' windows-uwp-arm ' : UWP + [ ' little_endian ' ] ,
' windows-uwp-x64 ' : UWP + [ ' x86_any ' , ' cpu64 ' , ' little_endian ' ] ,
' windows-uwp-x86 ' : UWP + [ ' x86_any ' , ' little_endian ' ] ,
2020-05-01 19:25:17 +02:00
# Mobile
2022-01-20 17:04:41 +01:00
' android-arm64-v8a ' : ANDROID + [ ' cpu64 ' ] ,
' android-armeabi-v7a ' : ANDROID ,
' android-x86 ' : ANDROID + [ ' x86_any ' ] ,
' android-x86_64 ' : ANDROID + [ ' x86_any ' , ' cpu64 ' ] ,
2022-04-04 17:35:11 +02:00
' ios ' : MOBILE_LE + [ ' physfs ' , ' c++14 ' , ' c++11 ' ] ,
' ios9 ' : MOBILE_LE + [ ' physfs ' , ' c++14 ' , ' c++11 ' ] ,
' ios-arm64 ' : MOBILE_LE + [ ' cpu64 ' , ' physfs ' , ' thread-local ' , ' c++14 ' , ' c++11 ' ] ,
' tvos-arm64 ' : MOBILE_LE + [ ' cpu64 ' , ' physfs ' , ' thread-local ' , ' c++14 ' , ' c++11 ' ] ,
' qnx ' : MOBILE_LE + [ ' physfs ' , ' thread-local ' , ' c++14 ' , ' c++11 ' , ' jvm ' ] , # Unsure about usb and thread-local
2020-05-01 19:25:17 +02:00
# Desktop
' linux-x64 ' : DESKTOP_X64 ,
' windows-x64 ' : DESKTOP_X64 ,
' osx-x64 ' : DESKTOP_X64 ,
2022-01-20 17:04:41 +01:00
' linux-i686 ' : DESKTOP_X86 ,
' windows-i686 ' : DESKTOP_X86 ,
' linux-arm7neonhf ' : DESKTOP_ARM32LE ,
' linux-armhf ' : DESKTOP_ARM32LE ,
2020-05-01 19:25:17 +02:00
' xbox-x86 ' : DESKTOP_X86 ,
2022-04-04 17:35:11 +02:00
' windows-msvc05-i686 ' : DESKTOP_X86_NO_CXX11 ,
' windows-msvc10-i686 ' : DESKTOP_X86_NO_CXX11 ,
' windows-msvc10-x64 ' : DESKTOP_X64_NO_CXX11 ,
' osx-ppc ' : [ x for x in DESKTOP_PPC if x != ' c++14 ' and x != ' c++11 ' ]
2020-05-01 19:25:17 +02:00
}
features_cores = {
' 3dengine ' : [ ' gl2 ' ] , # Should be gl2 or gles2 but current bugs prevent operating with gles2
' atari800 ' : [ ' libco ' ] ,
' blastem ' : [ ' x86_any ' ] ,
' boom3 ' : [ ' gl1 ' ] ,
2022-01-20 17:04:41 +01:00
' boom3-xp ' : [ ' gl1 ' ] ,
2020-05-01 19:25:17 +02:00
' bsnes ' : [ ' libco ' ] ,
' bsnes2014 ' : [ ' libco ' ] ,
2022-01-20 17:04:41 +01:00
' bsnes-libretro-cplusplus98 ' : [ ' libco ' ] ,
' bsnes-hd ' : [ ' libco ' ] ,
' bsnes-mercury ' : [ ' libco ' ] ,
' chailove ' : [ ' physfs ' , ' thread-local ' , ' threads ' ] ,
2020-05-01 19:25:17 +02:00
' citra ' : [ ' gfxaccel ' ] ,
2022-01-20 17:04:41 +01:00
' citra2018 ' : [ ' gfxaccel ' ] ,
' Craft ' : [ ' gfxaccel ' ] ,
' chailove ' : [ ' c++14 ' ] ,
2020-05-01 19:25:17 +02:00
' dolphin ' : [ ' cpu64 ' , ' jit ' ] ,
2022-01-20 17:04:41 +01:00
' dosbox-svn ' : [ ' libco ' ] ,
' dosbox-core ' : [ ' threads ' ] ,
2022-04-04 17:35:11 +02:00
' dosbox-pure ' : [ ' c++11 ' , ' threads ' ] ,
2020-05-01 19:25:17 +02:00
' ffmpeg ' : [ ' threads ' ] ,
' flycast ' : [ ' gfxaccel ' ] ,
2022-01-20 17:04:41 +01:00
' flycast-upstream ' : [ ' gfxaccel ' ] ,
2020-05-01 19:25:17 +02:00
' frodo ' : [ ' libco ' ] ,
' hatari ' : [ ' libco ' ] ,
' gpsp ' : [ ' libco ' ] ,
' ishiiruka ' : [ ' cpu64 ' ] ,
' kronos ' : [ ' gl3 ' ] ,
2022-01-20 17:04:41 +01:00
' mupen64plus ' : [ ' gfxaccel ' , ' libco ' ] ,
2022-04-04 17:35:11 +02:00
' neocd ' : [ ' c++11 ' ] ,
' Omicron ' : [ ' gfxaccel ' , ' jvm ' ] ,
2022-01-20 17:04:41 +01:00
' OpenLara ' : [ ' gfxaccel ' ] ,
' parallel-n64 ' : [ ' gfxaccel ' , ' libco ' ] ,
2022-04-04 17:35:11 +02:00
' pcem ' : [ ' threads ' ] ,
2020-05-01 19:25:17 +02:00
' play ' : [ ' gfxaccel ' ] ,
' redbook ' : [ ' cdrom ' ] ,
' remotejoy ' : [ ' usb ' ] ,
2022-04-04 17:35:11 +02:00
' retro8 ' : [ ' c++11 ' ] ,
2022-01-20 17:04:41 +01:00
' REminiscence ' : [ ' libco ' ] ,
2020-05-01 19:25:17 +02:00
' scummvm ' : [ ' libco ' ] ,
2022-01-20 17:04:41 +01:00
' ThePowderToy ' : [ ' threads ' ] ,
' tic80 ' : [ ' little_endian ' ] ,
2022-04-04 17:35:11 +02:00
' uae ' : [ ' threads ' ] ,
2020-05-01 19:25:17 +02:00
' vitaquake3 ' : [ ' gl1 ' ] ,
' vitavoyager ' : [ ' gl1 ' ] ,
' yabasanshiro ' : [ ' gfxaccel ' ]
}
def strip_suffix ( s , suffix ) :
if s . endswith ( suffix ) :
return s [ : - len ( suffix ) ]
return s
def strip_suffixes ( s , suffixes ) :
r = s
2022-01-20 17:04:41 +01:00
for suffix in suffixes + suffixes + suffixes :
2020-05-01 19:25:17 +02:00
r = strip_suffix ( r , suffix )
return r
def strip_prefix ( s , prefix ) :
if s . startswith ( prefix ) :
return s [ len ( prefix ) : ]
return s
def strip_prefixes ( s , prefixes ) :
r = s
for prefix in prefixes :
r = strip_prefix ( r , prefix )
return r
def file_to_platform ( fname ) :
2022-01-20 17:04:41 +01:00
s = strip_suffixes ( fname , [
" -legacy " , " -mingw " ,
# Mupen64
" -gles2 " , " -gles3 " ,
] + [ " - " + x for x in SUBCORE_SUFFIXES ] )
s = strip_prefixes ( s , [ " libretro- " , " build- " , " static- " ,
" retroarch- " , " dummy- " , " deps: " , " test: " ] )
# for infix in ["msvc05", "msvc10"]:
# s = s.replace("-" + infix + "-", "-")
2022-04-04 17:35:11 +02:00
mp = {
' code_quality ' : None ,
' ios-9 ' : ' ios9 ' ,
' trigger_static-cores ' : None ,
" android " : None ,
' osx ' : None ,
' switch ' : None
}
2022-01-20 17:04:41 +01:00
if s in mp :
s = mp [ s ]
subcore = list ( filter ( lambda x : " - " + x + " - " in fname
or fname . endswith ( " - " + x ) , SUBCORE_SUFFIXES ) )
return ( s , " - " . join ( subcore ) )
def repo_to_core ( repname ) :
2022-04-04 17:35:11 +02:00
s = strip_suffixes ( repname , [ " -nx " , " -libretro " , " _libretro " ] )
2022-01-20 17:04:41 +01:00
s = strip_prefixes ( s , [ " libretro- " ] )
2020-05-01 19:25:17 +02:00
return s
2022-01-20 17:04:41 +01:00
def page_get ( base ) :
per_page = 20
res = [ ]
for page in range ( 1 , 30 ) :
add = requests . get ( base + ( ' per_page= %d &page= %d ' % ( per_page , page ) ) ) . json ( )
res + = add
if len ( add ) != per_page :
return res
return res
2020-05-01 19:25:17 +02:00
2022-01-20 17:04:41 +01:00
def parse_pipelines ( projectid , sha ) :
pipelines = requests . get ( ' https:// %s /api/v4/projects/ %d /pipelines?sha= %s &per_page=20 ' % ( hostname , projectid , sha ) ) . json ( )
for pipeline in pipelines :
if pipeline [ ' status ' ] == ' success ' :
# print(pipeline)
return page_get ( ' https:// %s /api/v4/projects/ %d /pipelines/ %d /jobs? ' % ( hostname , projectid , pipeline [ ' id ' ] ) )
return None
projects_all = page_get ( ' https:// %s /api/v4/projects?simple=true& ' % hostname )
2020-05-01 19:25:17 +02:00
2022-01-20 17:04:41 +01:00
projects = list ( filter ( lambda x : x [ ' namespace ' ] [ ' path ' ] == namespace , projects_all ) )
for project in projects :
print ( project [ ' path_with_namespace ' ] )
projectid = project [ ' id ' ]
core_base = repo_to_core ( project [ ' path ' ] )
if core_base == ' RetroArch ' :
continue
commits = requests . get ( ' https:// %s /api/v4/projects/ %d /repository/commits?ref_name= %s ' % ( hostname , projectid , project [ ' default_branch ' ] ) ) . json ( )
# print(commits[0])
jobs = None
for commit in commits :
jobs = parse_pipelines ( projectid , commit [ ' id ' ] )
if jobs is not None :
break
if jobs is None :
jobs = [ ]
if not jobs :
allcores . add ( core_base )
for job in jobs :
# print(job)
( platform , subcore ) = file_to_platform ( job [ ' name ' ] )
if platform is None :
continue
if subcore :
core = core_base + " - " + subcore
else :
core = core_base
2020-05-01 19:25:17 +02:00
allplatformset . add ( platform )
2022-01-20 17:04:41 +01:00
allcores . add ( core )
k = ( platform , core )
if k not in coremap :
coremap [ k ] = [ ]
coremap [ k ] . append ( { ' status ' : job [ ' status ' ] } )
2020-05-01 19:25:17 +02:00
allplatforms = sorted ( allplatformset )
cf = open ( " comptable.csv " , " w " )
c = csv . writer ( cf )
c . writerow ( [ " " ] + allplatforms )
for core in allcores :
row = [ core ]
for platform in allplatforms :
k = ( platform , core )
if k not in coremap :
status = MISSING
else :
2022-01-20 17:04:41 +01:00
status = OK if any ( map ( lambda x : x [ ' status ' ] , coremap [ k ] ) ) else BROKEN
2020-05-01 19:25:17 +02:00
corestatus [ k ] = status
if core in features_cores and platform in features_platforms :
missing = set ( features_cores [ core ] ) - set ( features_platforms [ platform ] )
if missing :
corereason [ k ] = ' , ' . join ( missing )
for core in sorted ( allcores ) :
2022-01-20 17:04:41 +01:00
if core in ( ' dosbox-libretro ' , ) :
continue
2020-05-01 19:25:17 +02:00
row = [ core ]
for platform in allplatforms :
k = ( platform , core )
st = corestatus [ k ]
s = st
if st != OK and k in corereason :
s + = " ( " + corereason [ k ] + " ) "
if st == OK and k in corereason :
print ( " %s is enabled on %s despite %s " % ( core , platform , corereason [ k ] ) )
row + = [ s ]
c . writerow ( row )
cf . close ( )