Skip to content

Commit

Permalink
Move LintManager to core, check that python is >= 3.8 in conda.yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioz committed Aug 5, 2023
1 parent 0264902 commit c234b5f
Show file tree
Hide file tree
Showing 34 changed files with 2,887 additions and 408 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/pre-release-robocorp-code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ jobs:
- name: Yarn install
run: yarn install

- name: Set up Python 3.7
- name: Set up Python 3.9
uses: actions/setup-python@v1
with:
python-version: 3.7
python-version: 3.9

- name: Install deps
run: pip install --upgrade pip fire twine wheel setuptools
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-robocorp-code-vscode.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ jobs:
node-version: 16.x
- name: Yarn install
run: yarn install
- name: Set up Python 3.7
- name: Set up Python 3.9
uses: actions/setup-python@v1
with:
python-version: 3.7
python-version: 3.9
- name: Install deps
run: pip install --upgrade pip fire twine wheel setuptools
- name: Vendor robocorp_ls_core
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,5 @@ robotframework-intellij/.gradle

# virtual environment
.venv/

*.robolog
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from typing import Optional

from robocorp_ls_core.basic import overrides
from robocorp_ls_core.python_ls import PythonLanguageServer
from robocorp_ls_core.robotframework_log import get_logger
from robocorp_ls_core.protocols import IConfig
from robocorp_ls_core.python_ls import BaseLintManager, PythonLanguageServer
from robocorp_ls_core.robotframework_log import get_logger

log = get_logger(__name__)

Expand Down Expand Up @@ -98,11 +100,8 @@ def m_text_document__semantic_tokens__full(self, textDocument=None):
# return {"data": [1, 0, 10, 1, 0, 1, 0, 10, 1, 0]}
return {"data": []}

def lint(self, doc_uri, is_saved, content_changes=None):
pass

def cancel_lint(self, doc_uri):
pass
def _create_lint_manager(self) -> Optional[BaseLintManager]:
return None

def _create_config(self) -> IConfig:
from robocorp_ls_core.config import Config
Expand Down
5 changes: 5 additions & 0 deletions robocorp-code/.settings/org.python.pydev.analysis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
MYPY_USE_CONSOLE: false
SEARCH_MYPY_LOCATION: SEARCH
USE_MYPY: true
MYPY_ADD_PROJECT_FOLDERS_TO_MYPYPATH: true
MYPY_FILE_LOCATION: ''
41 changes: 33 additions & 8 deletions robocorp-code/.settings/org.python.pydev.yaml
Original file line number Diff line number Diff line change
@@ -1,30 +1,55 @@
ADD_COMMENTS_AT_INDENT: false
ADD_NEW_LINE_AT_END_OF_FILE: true
AUTOPEP8_PARAMETERS: ''
BLACK_PARAMETERS: '--fast'
BLACK_FORMATTER_FILE_LOCATION: ''
BLACK_FORMATTER_LOCATION_OPTION: LOCATION_SEARCH
BLACK_PARAMETERS: --fast
BLANK_LINES_INNER: 1
BLANK_LINES_TOP_LEVEL: 2
BREAK_IMPORTS_MODE: ESCAPE
DATE_FIELD_FORMAT: yyyy-MM-dd
DATE_FIELD_NAME: __updated__
DELETE_UNUSED_IMPORTS: false
ENABLE_DATE_FIELD_ACTION: false
FORMATTER_STYLE: BLACK
FORMAT_BEFORE_SAVING: true
FORMAT_ONLY_CHANGED_LINES: false
FROM_IMPORTS_FIRST: false
GROUP_IMPORTS: true
IMPORT_ENGINE: IMPORT_ENGINE_ISORT
ISORT_FILE_LOCATION: ''
ISORT_LOCATION_OPTION: LOCATION_SEARCH
ISORT_PARAMETERS: ''
MANAGE_BLANK_LINES: true
MULTILINE_IMPORTS: true
MULTI_BLOCK_COMMENT_CHAR: =
MULTI_BLOCK_COMMENT_SHOW_ONLY_CLASS_NAME: true
MULTI_BLOCK_COMMENT_SHOW_ONLY_FUNCTION_NAME: true
MYPY_ADD_PROJECT_FOLDERS_TO_MYPYPATH: true
MYPY_ARGS: --follow-imports=silent --show-column-numbers --namespace-packages --explicit-package-bases
MYPY_FILE_LOCATION: ''
MYPY_USE_CONSOLE: true
PYDEV_TEST_RUNNER: '2'
PYDEV_TEST_RUNNER_DEFAULT_PARAMETERS: --capture=no -W ignore::DeprecationWarning -n 0 --tb=native -vv
PYDEV_TEST_RUNNER_DEFAULT_PARAMETERS: --capture=no -W ignore::DeprecationWarning -n
0 --tb=native -vv --force-regen --assert=plain
PYDEV_USE_PYUNIT_VIEW: true
RUFF_ARGS: ''
RUFF_FILE_LOCATION: ''
RUFF_USE_CONSOLE: false
SAVE_ACTIONS_ONLY_ON_WORKSPACE_FILES: true
SORT_IMPORTS_ON_SAVE: false
SEARCH_MYPY_LOCATION: SEARCH
SEARCH_RUFF_LOCATION: SEARCH
SINGLE_BLOCK_COMMENT_ALIGN_RIGHT: true
SINGLE_BLOCK_COMMENT_CHAR: '-'
SORT_IMPORTS_ON_SAVE: true
SORT_NAMES_GROUPED: false
SPACES_BEFORE_COMMENT: '2'
SPACES_IN_START_COMMENT: '1'
TRIM_EMPTY_LINES: true
TRIM_MULTILINE_LITERALS: true
USE_ASSIGN_WITH_PACES_INSIDER_PARENTESIS: false
USE_MYPY: true
USE_OPERATORS_WITH_SPACE: true
USE_RUFF: true
USE_SPACE_AFTER_COMMA: true
USE_SPACE_FOR_PARENTESIS: false
MYPY_USE_CONSOLE: false
SEARCH_MYPY_LOCATION: SEARCH
USE_MYPY: true
MYPY_ADD_PROJECT_FOLDERS_TO_MYPYPATH: true
MYPY_FILE_LOCATION: ''
1 change: 1 addition & 0 deletions robocorp-code/bin/create_env/conda.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ channels:
dependencies:
- python=3.9.13 # https://pyreadiness.org/3.9/
- pip=22.1.2 # https://pip.pypa.io/en/stable/news/
- pyyaml=6.0
- pip:
- robocorp-inspector==0.9.1 # https://github.com/robocorp/inspector/blob/master/CHANGELOG.md
- robotframework==5.0.1 # https://github.com/robotframework/robotframework/blob/master/doc/releasenotes/rf-5.0.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dependencies:
- python=3.9.13 # https://pyreadiness.org/3.9/
- pip=22.1.2 # https://pip.pypa.io/en/stable/news/
- python.app=1.3 # https://anaconda.org/conda-forge/python.app/files
- pyyaml=6.0
- pip:
- robocorp-inspector==0.9.1 # https://github.com/robocorp/inspector/blob/master/CHANGELOG.md
- robotframework==5.0.1 # https://github.com/robotframework/robotframework/blob/master/doc/releasenotes/rf-5.0.1.rst
1 change: 1 addition & 0 deletions robocorp-code/bin/create_env/conda_vscode_linux_amd64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies:
- pip=22.1.2 # https://pip.pypa.io/en/stable/news/
- pyside2=5.15.4 # https://wiki.qt.io/Qt_for_Python
- qtpy=2.3.0 # https://github.com/spyder-ide/qtpy/blob/master/CHANGELOG.md
- pyyaml=6.0
- pip:
- robocorp-inspector==0.9.1 # https://github.com/robocorp/inspector/blob/master/CHANGELOG.md
- robotframework==5.0.1 # https://github.com/robotframework/robotframework/blob/master/doc/releasenotes/rf-5.0.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dependencies:
- python=3.9.13 # https://pyreadiness.org/3.9/
- pip=22.1.2 # https://pip.pypa.io/en/stable/news/
- pywin32=303 # https://github.com/mhammond/pywin32/blob/main/CHANGES.txt
- pyyaml=6.0
- pip:
- robocorp-inspector==0.9.1 # https://github.com/robocorp/inspector/blob/master/CHANGELOG.md
- robotframework==5.0.1 # https://github.com/robotframework/robotframework/blob/master/doc/releasenotes/rf-5.0.1.rst
204 changes: 204 additions & 0 deletions robocorp-code/src/robocorp_code/_lint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import os
import weakref
from typing import List, Optional

from robocorp_ls_core.basic import overrides
from robocorp_ls_core.lsp import DiagnosticsTypedDict, LSPMessages
from robocorp_ls_core.protocols import IEndPoint, IMonitor, IWorkspace
from robocorp_ls_core.python_ls import BaseLintInfo, BaseLintManager
from robocorp_ls_core.robotframework_log import get_logger

from robocorp_code.protocols import IRcc
from robocorp_code.robocorp_language_server import RobocorpLanguageServer

log = get_logger(__name__)


class DiagnosticsConfig:
analyze_versions = True
analyze_rcc = True


def collect_conda_yaml_diagnostics(
workspace: IWorkspace, conda_yaml_uri: str, monitor: Optional[IMonitor]
) -> List[DiagnosticsTypedDict]:
from robocorp_code.deps import analyzer

if not DiagnosticsConfig.analyze_versions:
return []

doc = workspace.get_document(conda_yaml_uri, accept_from_file=True)
if doc is None:
return []
if monitor:
monitor.check_cancelled()
return list(analyzer.Analyzer(doc.source, doc.path).iter_issues())


def collect_rcc_configuration_diagnostics(
rcc: IRcc, robot_yaml_fs_path
) -> List[DiagnosticsTypedDict]:
import json

from robocorp_ls_core.lsp import DiagnosticSeverity

ret: List[DiagnosticsTypedDict] = []

if not DiagnosticsConfig.analyze_rcc:
return ret

action_result = rcc.configuration_diagnostics(robot_yaml_fs_path)
if action_result.success:
json_contents = action_result.result
if not json_contents:
return ret

as_dict = json.loads(json_contents)
checks = as_dict.get("checks", [])
ret = []

CategoryLockFile = 1020
CategoryLockPid = 1021

if isinstance(checks, (list, tuple)):
for check in checks:
if isinstance(check, dict):
status = check.get("status", "ok").lower()

if status != "ok":
if check.get("category") in (
CategoryLockFile,
CategoryLockPid,
):
continue

# Default is error (for fail/fatal)
severity = DiagnosticSeverity.Error

if status in ("warn", "warning"):
severity = DiagnosticSeverity.Warning
elif status in ("info", "information"):
severity = DiagnosticSeverity.Information

# The actual line is not given by rcc, so, put
# all errors in the first 2 lines.
message = check.get("message", "<unable to get error message>")

url = check.get("url")
if url:
message += f" -- see: {url} for more information."
dct: DiagnosticsTypedDict = {
"range": {
"start": {"line": 0, "character": 0},
"end": {"line": 1, "character": 0},
},
"severity": severity,
"source": "robocorp-code",
"message": message,
}
ret.append(dct)
return ret


class _CurrLintInfo(BaseLintInfo):
def __init__(
self,
weak_robocorp_language_server: "weakref.ref[RobocorpLanguageServer]",
rcc: IRcc,
lsp_messages: LSPMessages,
doc_uri,
is_saved,
weak_lint_manager,
) -> None:
self._rcc: IRcc = rcc
self._weak_robocorp_language_server = weak_robocorp_language_server
BaseLintInfo.__init__(self, lsp_messages, doc_uri, is_saved, weak_lint_manager)

@overrides(BaseLintInfo._do_lint)
def _do_lint(self) -> None:
from concurrent import futures

from robocorp_ls_core import uris

is_saved = self.is_saved
doc_uri = self.doc_uri

if doc_uri.endswith("conda.yaml") or doc_uri.endswith("robot.yaml"):
robot_yaml_fs_path = uris.to_fs_path(doc_uri)
if robot_yaml_fs_path.endswith("conda.yaml"):
p = os.path.dirname(robot_yaml_fs_path)
for _ in range(3):
target = os.path.join(p, "robot.yaml")
if target and os.path.exists(target):
robot_yaml_fs_path = target
break
else:
# We didn't find the 'robot.yaml' for the 'conda.yaml'
# bail out.
return

# Get the executor service from the endpoint
endpoint = self._lsp_messages.endpoint

# When a document is saved, if it's a conda.yaml or a robot.yaml,
# validate it with RCC.
if is_saved:
executor_service: futures.ThreadPoolExecutor = getattr(
endpoint, "executor_service"
)

future_diagnostics = executor_service.submit(
collect_rcc_configuration_diagnostics,
self._rcc,
robot_yaml_fs_path,
)

found = []
# Ok, we started collecting RCC diagnostics in a thread. We
# can now also collect other diagnostics here.
if doc_uri.endswith("conda.yaml"):
robocorp_language_server = self._weak_robocorp_language_server()
if robocorp_language_server is not None:
ws = robocorp_language_server.workspace
if ws is not None:
found.extend(
collect_conda_yaml_diagnostics(ws, doc_uri, self._monitor)
)

if is_saved:
found.extend(future_diagnostics.result())

self._lsp_messages.publish_diagnostics(doc_uri, found)


class LintManager(BaseLintManager):
def __init__(
self,
robocorp_language_server: RobocorpLanguageServer,
rcc: IRcc,
lsp_messages,
endpoint: IEndPoint,
read_queue,
) -> None:

self._rcc: IRcc = rcc
self._weak_robocorp_language_server = weakref.ref(robocorp_language_server)
BaseLintManager.__init__(self, lsp_messages, endpoint, read_queue)

@overrides(BaseLintManager._create_curr_lint_info)
def _create_curr_lint_info(
self, doc_uri: str, is_saved: bool, timeout: float
) -> Optional[BaseLintInfo]:
# Note: this call must be done in the main thread.
weak_lint_manager = weakref.ref(self)

log.debug("Schedule lint for: %s", doc_uri)
curr_info = _CurrLintInfo(
self._weak_robocorp_language_server,
self._rcc,
self._lsp_messages,
doc_uri,
is_saved,
weak_lint_manager,
)
return curr_info
Empty file.
Loading

0 comments on commit c234b5f

Please sign in to comment.