Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(ci): add script and workflow for auto-updating schema #286

Merged
merged 6 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Update schema in Dependabot PR

on:
pull_request:
branches:
- master

permissions:
pull-requests: write
repository-projects: write

jobs:
update_schema:
name: Run schema update
runs-on: ubuntu-latest

if: github.actor == 'dependabot[bot]'
steps:
- uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use v5

with:
python-version: 3.11

- name: Update schema
run: |
make update-schema

- name: Check for modified files
id: git-check
run: echo ::set-output name=modified::$(if [ -n "$(git status --porcelain)" ]; then echo "true"; else echo "false"; fi)

- name: Update changes in the PR
if: steps.git-check.outputs.modified == 'true'
run: |
git config --global user.name 'workflow'
git config --global user.email '[email protected]'
git add -A
git commit -m '[automated commit] update schema'
git push
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ fix:
autoflake --in-place .
black --preview .
isort .

.PHONY: update-schema
update-schema:
python3 ./scripts/update_schema.py
89 changes: 89 additions & 0 deletions scripts/update_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from json import dump, load
from typing import Any, Dict, Optional
from urllib.request import urlopen
import os

DIRNAME = os.path.dirname(os.path.abspath(__file__))
PYRIGHTCONFIG_SCHEMA_ID = 'sublime://pyrightconfig'
PYRIGHT_CONFIGURATION_SCHEMA_URL = 'https://raw.githubusercontent.com/microsoft/pyright/main/packages/vscode-pyright/schemas/pyrightconfig.schema.json' # noqa: E501
SUBLIME_PACKAGE_JSON_PATH = os.path.join(DIRNAME, '..', 'sublime-package.json')
# Keys that are in the schema for pyrighconfig.json but should not raise a comment when not present in LSP schema.
IGNORED_PYRIGHTCONFIG_KEYS = [
'defineConstant',
'exclude',
'executionEnvironments',
'ignore',
'include',
'pythonPlatform',
'pythonVersion',
'strict',
'typeshedPath',
'venv',
'verboseOutput',
]

JSON = Dict[str, Any]


def main() -> None:
pyrightconfig_schema_json = None
sublime_package_json = None
with urlopen(PYRIGHT_CONFIGURATION_SCHEMA_URL) as response:
pyrightconfig_schema_json = load(response)
with open(SUBLIME_PACKAGE_JSON_PATH, 'r', encoding='utf-8') as f:
sublime_package_json = load(f)
update_schema(sublime_package_json, pyrightconfig_schema_json)
with open(SUBLIME_PACKAGE_JSON_PATH, 'w', encoding='utf-8') as f:
dump(sublime_package_json, f, indent=2)
print('sublime-package.json file updated! If there are any changes then make sure to also update the LSP part of the configuration.') # noqa: E501


def update_schema(sublime_package_json: JSON, pyrightconfig_schema_json: JSON) -> None:
pyrightconfig_contribution: Optional[JSON] = None
lsp_pyright_contribution: Optional[JSON] = None
for contribution in sublime_package_json['contributions']['settings']:
if '/pyrightconfig.json' in contribution['file_patterns']:
pyrightconfig_contribution = contribution
elif '/LSP-pyright.sublime-settings' in contribution['file_patterns']:
lsp_pyright_contribution = contribution
if not pyrightconfig_contribution or not lsp_pyright_contribution:
raise Exception('Expected contributions not found in sublime-package.json!')
# Update to latest pyrightconfig schema.
pyrightconfig_contribution['schema'] = pyrightconfig_schema_json
# Add ID.
pyrightconfig_contribution['schema']['$id'] = PYRIGHTCONFIG_SCHEMA_ID
# Update LSP settings to reference options from the pyrightconfig schema.
settings_properties: JSON = lsp_pyright_contribution['schema']['definitions']['PluginConfig']['properties']['settings']['properties'] # noqa: E501
pyrightconfig_properties: JSON = pyrightconfig_contribution['schema']['properties']
for setting_key, setting_value in settings_properties.items():
# get last dotted component.
last_component_key = setting_key.split('.').pop()
if last_component_key in pyrightconfig_properties:
update_property_ref(last_component_key, setting_value, pyrightconfig_properties)
if setting_key == 'python.analysis.diagnosticSeverityOverrides':
overrides_properties: JSON = setting_value['properties']
for override_key, override_value in overrides_properties.items():
if override_key in pyrightconfig_properties:
update_property_ref(override_key, override_value, pyrightconfig_properties)
else:
del overrides_properties[override_key]
# Check if there are any properties that might need to be added to the LSP properties.
# If the property is neither in `diagnosticSeverityOverrides`, the root LSP settings nor in ignored keys
# then it might have to be added manually.
all_settings_keys = list(map(lambda k: k.split('.').pop(), settings_properties.keys()))
all_overrides_keys = settings_properties['python.analysis.diagnosticSeverityOverrides']['properties'].keys()
for pyrightconfig_key in pyrightconfig_properties.keys():
if pyrightconfig_key not in all_settings_keys \
and pyrightconfig_key not in all_overrides_keys \
and pyrightconfig_key not in IGNORED_PYRIGHTCONFIG_KEYS:
print(pyrightconfig_key)


def update_property_ref(property_key: str, property_schema: JSON, pyrightconfig_properties: JSON) -> None:
property_schema.clear()
pyrightconfig_property_id: str = pyrightconfig_properties[property_key]['$id']
property_schema['$ref'] = PYRIGHTCONFIG_SCHEMA_ID + pyrightconfig_property_id


if __name__ == '__main__':
main()
Loading
Loading