tree-sitter/treesitter_grammar.req
Martin Pluskal 4f0bc7765f Accepting request 1162313 from home:Thaodan:editors
- Add workaround to packaging macros for RPM being to old on current Leap
- Add workaround for Python below 3.9 on Leap

OBS-URL: https://build.opensuse.org/request/show/1162313
OBS-URL: https://build.opensuse.org/package/show/editors/tree-sitter?expand=0&rev=25
2024-03-27 08:35:27 +00:00

99 lines
3.8 KiB
Python

#!/usr/bin/python3
"""Scan grammar JavaScript sources for their dependencies"""
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2024 Björn Bidar
# pylint: disable=invalid-name
import platform
import fileinput
import re
from typing import Optional
from pathlib import Path
if platform.sys.version_info.minor < 9:
def remove_prefix(text, prefix):
if text.startswith(prefix):
return text[len(prefix):]
return text
def remove_suffix(text, suffix):
if text.endswith(suffix):
return text[:-len(suffix):]
return text
treeSitterGrammarSrcPath = "/usr/include/tree_sitter"
treeSitterGrammarSymbolToken = "treesitter_grammar_src"
grammarPaths = []
def resolveFile(grammarFile: str) -> str:
"""Resolve GRAMMARFILE from grammarPaths return found file"""
fullGrammarFilePath = Path(grammarFile)
currentGrammarPath = fullGrammarFilePath.parent
currentGrammarFile = Path(grammarFile)
if currentGrammarPath != Path('.') and currentGrammarPath.parts[0] == "..":
# resolve path relative to file found last
currentGrammarPath = grammarPaths[-1] / fullGrammarFilePath
if not currentGrammarPath.exists():
return False
return currentGrammarPath
if currentGrammarPath.is_absolute():
grammarPaths.append(currentGrammarPath)
if Path(grammarFile).exists():
return fullGrammarFilePath
for path in grammarPaths:
maybeFound = path / currentGrammarFile
if maybeFound.exists():
return maybeFound.exists()
return False
def dummyRequire(requiredFile_fd: str, maxDepth: Optional[int] = 5 ) -> str:
"""Dummy version of node's require function that spits out dependency symbols"""
if maxDepth <= 0:
return
if not requiredFile_fd.endswith(".js"):
# Append .js to required file name in case is not specified
# we have to remove .js suffix later in any case.
requiredFile_fd+=".js"
resolvedFile_fd = resolveFile(requiredFile_fd)
if resolvedFile_fd:
try:
with open(resolvedFile_fd, mode='r', encoding='utf8') as requiredFile:
for r_line in requiredFile:
require_re = r'.*require\((.*)\).*'
requiredLvl2 = re.match(require_re, r_line)
#print(r_line)
if requiredLvl2 is not None:
if platform.sys.version_info.minor < 9:
requiredLvl2_grp_cleaned = \
remove_suffix(remove_prefix(requiredLvl2.group(1), "'"), "'")
requiredLvl2_grp_cleaned = \
remove_suffix(remove_prefix(requiredLvl2_grp_cleaned, "\""),
"\"")
else:
requiredLvl2_grp_cleaned = \
requiredLvl2.group(1).removeprefix("'").removesuffix("'")
requiredLvl2_grp_cleaned = \
requiredLvl2_grp_cleaned.removeprefix("\"").removesuffix("\"")
if not requiredLvl2_grp_cleaned.split('/')[0] == "..":
# Don't emit dependencies which are local
pass
dummyRequire(requiredLvl2_grp_cleaned, maxDepth - 1)
except FileNotFoundError:
pass
else:
if maxDepth == 5:
# In case we immediately fail to open the first grammar source file
return
# We only want to resolve dependencies outside of the package
print(f"{treeSitterGrammarSymbolToken}({Path(requiredFile_fd).parent})")
for line in fileinput.input():
line = line.rstrip('\n')
if line.endswith('.js'):
dummyRequire(line)