Skip to content

Commit

Permalink
Tweaked trigger to suggest using a config file (fixes #77)
Browse files Browse the repository at this point in the history
  • Loading branch information
suoto committed Jan 30, 2020
1 parent 3b7b973 commit db5d01b
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 22 deletions.
28 changes: 19 additions & 9 deletions hdl_checker/base_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
from hdl_checker.static_check import getStaticMessages
from hdl_checker.types import (
BuildFlagScope,
ConfigFileOrigin,
RebuildInfo,
RebuildLibraryUnit,
RebuildPath,
Expand Down Expand Up @@ -91,7 +92,9 @@
else:
JSONDecodeError = json.decoder.JSONDecodeError

WatchedFile = NamedTuple("WatchedFile", (("path", Path), ("last_read", float)))
WatchedFile = NamedTuple(
"WatchedFile", (("path", Path), ("last_read", float), ("origin", ConfigFileOrigin))
)


class BaseServer(object): # pylint: disable=useless-object-inheritance
Expand Down Expand Up @@ -159,8 +162,8 @@ def _clearLruCaches(self):
for meth in self._cached_methods:
meth.cache_clear()

def setConfig(self, filename):
# type: (Union[Path, str]) -> None
def setConfig(self, filename, origin):
# type: (Union[Path, str], ConfigFileOrigin) -> None
"""
Sets the configuration file. Calling this method will only trigger a
configuration update if the given file name is different what was
Expand All @@ -177,7 +180,7 @@ def setConfig(self, filename):
else:
return

self.config_file = WatchedFile(path, mtime)
self.config_file = WatchedFile(path, mtime, origin)
_logger.debug("Set config to %s", self.config_file)

def _updateConfigIfNeeded(self):
Expand All @@ -199,14 +202,17 @@ def _updateConfigIfNeeded(self):
if self.config_file.last_read >= file_mtime:
return

# Don't let the user hanging if adding sources is taking too long. Also
# need to notify when adding is done.
# Don't let the user hanging if adding sources is taking too long
# when there's no config file. Also need to notify when adding is
# done.
timer = Timer(
_HOW_LONG_IS_TOO_LONG,
self._handleUiInfo,
args=(_HOW_LONG_IS_TOO_LONG_MSG,),
)
timer.start()

if self.config_file.origin is ConfigFileOrigin.generated:
timer.start()

try:
config = json.load(open(str(self.config_file.path)))
Expand All @@ -215,7 +221,9 @@ def _updateConfigIfNeeded(self):

self.configure(config)

self.config_file = WatchedFile(self.config_file.path, file_mtime)
self.config_file = WatchedFile(
self.config_file.path, file_mtime, self.config_file.origin
)
_logger.debug("Updated config file to %s", self.config_file)
timer.cancel()

Expand Down Expand Up @@ -362,7 +370,9 @@ def _setupIfNeeded(self):
return

# Force config file out of to date to trigger reparsing
self.config_file = WatchedFile(self.config_file.path, 0)
self.config_file = WatchedFile(
self.config_file.path, 0, self.config_file.origin
)

def clean(self):
# type: (...) -> Any
Expand Down
4 changes: 2 additions & 2 deletions hdl_checker/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
import bottle # type: ignore

from hdl_checker import __version__ as version
from hdl_checker import types as t # pylint: disable=unused-import
from hdl_checker.base_server import BaseServer
from hdl_checker.builders.fallback import Fallback
from hdl_checker.path import Path
from hdl_checker.types import ConfigFileOrigin
from hdl_checker.utils import terminateProcess

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -88,7 +88,7 @@ def _getServerByProjectFile(project_file):
try:
project = Server(root_dir=root_dir)
if project_file is not None:
project.setConfig(project_file)
project.setConfig(project_file, origin=ConfigFileOrigin.user)
_logger.debug("Created new project server for '%s'", project_file)
except (IOError, OSError):
_logger.info("Failed to create checker, reverting to fallback")
Expand Down
7 changes: 3 additions & 4 deletions hdl_checker/lsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Union

import six

from pyls import lsp as defines # type: ignore
from pyls._utils import debounce # type: ignore
from pyls.python_ls import PythonLanguageServer # type: ignore
Expand All @@ -44,7 +43,7 @@
tAnyDesignUnit,
)
from hdl_checker.path import Path, TemporaryPath
from hdl_checker.types import Location, MarkupKind
from hdl_checker.types import ConfigFileOrigin, Location, MarkupKind
from hdl_checker.utils import getTemporaryFilename, logCalls, onNewReleaseFound

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -251,7 +250,7 @@ def _onConfigUpdate(self, options):
path = self._getProjectFilePath(options)

try:
self.checker.setConfig(path)
self.checker.setConfig(path, origin=ConfigFileOrigin.user)
return
except UnknownParameterError as exc:
_logger.info("Failed to read config from %s: %s", path, exc)
Expand All @@ -274,7 +273,7 @@ def _onConfigUpdate(self, options):
# Write this to a file and tell the server to use it
auto_project_file = getTemporaryFilename(AUTO_PROJECT_FILE_NAME)
json.dump(config, open(auto_project_file, "w"))
self.checker.setConfig(auto_project_file)
self.checker.setConfig(auto_project_file, origin=ConfigFileOrigin.generated)

def _getProjectFilePath(self, options=None):
# type: (...) -> str
Expand Down
49 changes: 42 additions & 7 deletions hdl_checker/tests/test_base_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
from hdl_checker.path import Path
from hdl_checker.types import (
BuildFlagScope,
ConfigFileOrigin,
FileType,
Location,
RebuildLibraryUnit,
Expand Down Expand Up @@ -141,7 +142,7 @@ def test(handle_ui_info):
open(source, "w").write("")

project = DummyServer(_Path(path))
project.setConfig(Path(config))
project.setConfig(_Path(config), origin=ConfigFileOrigin.generated)
# Get messages of anything to trigger reading the config
project.getMessagesByPath(Path(source))

Expand All @@ -151,6 +152,34 @@ def test(handle_ui_info):

removeIfExists(path)

@it.should( # type: ignore
"not warn when setup is taking too long if the user provides the config file"
)
@patch("hdl_checker.base_server._HOW_LONG_IS_TOO_LONG", 0.1)
@patch.object(
hdl_checker.base_server.BaseServer, "configure", lambda *_: time.sleep(0.5)
)
@patch("hdl_checker.tests.DummyServer._handleUiInfo")
def test(handle_ui_info):

path = tempfile.mkdtemp()

config = p.join(path, "config.json")
source = p.join(path, "source.vhd")

# Make sure the files exist
open(config, "w").write("")
open(source, "w").write("")

project = DummyServer(_Path(path))
project.setConfig(Path(config), origin=ConfigFileOrigin.user)
# Get messages of anything to trigger reading the config
project.getMessagesByPath(Path(source))

handle_ui_info.assert_not_called()

removeIfExists(path)

@it.should( # type: ignore
"not warn when setup takes less than _HOW_LONG_IS_TOO_LONG"
)
Expand All @@ -166,7 +195,7 @@ def test(handle_ui_info):
open(source, "w").write("")

project = DummyServer(_Path(path))
project.setConfig(Path(config))
project.setConfig(Path(config), origin=ConfigFileOrigin.user)
# Get messages of anything to trigger reading the config
project.getMessagesByPath(Path(source))

Expand Down Expand Up @@ -220,7 +249,7 @@ def setup():
def test():
project = DummyServer(_Path("nonexisting"))
with it.assertRaises(FileNotFoundError):
project.setConfig(str(it.project_file))
project.setConfig(str(it.project_file), origin=ConfigFileOrigin.user)

with it.having("no project file at all"):

Expand Down Expand Up @@ -308,7 +337,7 @@ def setup():
}
)

it.project.setConfig(it.config_file)
it.project.setConfig(it.config_file, origin=ConfigFileOrigin.user)

@it.should("use MockBuilder builder") # type: ignore
def test():
Expand Down Expand Up @@ -344,7 +373,7 @@ def test():
"hdl_checker.base_server.WatchedFile.__init__", side_effect=[None]
) as watched_file:
old = it.project.config_file
it.project.setConfig(it.config_file)
it.project.setConfig(it.config_file, origin=ConfigFileOrigin.user)
it.project._updateConfigIfNeeded()
it.assertEqual(it.project.config_file, old)
watched_file.assert_not_called()
Expand Down Expand Up @@ -430,7 +459,10 @@ def test(handle_ui_warning):
@patch("hdl_checker.base_server.json.dump")
def test(_):
with PatchBuilder():
it.project.setConfig(Path(p.join(TEST_PROJECT, "vimhdl.prj")))
it.project.setConfig(
Path(p.join(TEST_PROJECT, "vimhdl.prj")),
origin=ConfigFileOrigin.user,
)
it.project._updateConfigIfNeeded()

entity_a = _SourceMock(
Expand Down Expand Up @@ -614,7 +646,10 @@ def setup(handle_ui_info):

with PatchBuilder():
it.project = DummyServer(_Path(TEST_TEMP_PATH))
it.project.setConfig(Path(p.join(TEST_PROJECT, "vimhdl.prj")))
it.project.setConfig(
Path(p.join(TEST_PROJECT, "vimhdl.prj")),
origin=ConfigFileOrigin.user,
)
it.project._updateConfigIfNeeded()
handle_ui_info.assert_called_once_with("Added 10 sources")

Expand Down
5 changes: 5 additions & 0 deletions hdl_checker/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,8 @@ class MarkupKind(Enum):

# A location range within a source file
Range = NamedTuple("Range", (("start", Location), ("end", Optional[Location])))

class ConfigFileOrigin(str, Enum):
"Specifies tracked design unit types"
user = "user"
generated = "generated"

0 comments on commit db5d01b

Please sign in to comment.