6
6
from subprocess import PIPE , Popen
7
7
from typing import Dict , List
8
8
9
- from lsprotocol .converters import get_converter
10
9
from lsprotocol .types import (
11
10
CodeAction ,
12
11
CodeActionContext ,
26
25
27
26
from pylsp_ruff .ruff import Check as RuffCheck
28
27
from pylsp_ruff .ruff import Fix as
8000
RuffFix
28
+ from pylsp_ruff .settings import PluginSettings , get_converter
29
29
30
30
log = logging .getLogger (__name__ )
31
31
converter = get_converter ()
52
52
def pylsp_settings ():
53
53
log .debug ("Initializing pylsp_ruff" )
54
54
# this plugin disables flake8, mccabe, and pycodestyle by default
55
- return {
55
+ settings = {
56
56
"plugins" : {
57
- "ruff" : {
58
- "enabled" : True ,
59
- "config" : None ,
60
- "exclude" : None ,
61
- "executable" : "ruff" ,
62
- "ignore" : None ,
63
- "extendIgnore" : None ,
64
- "lineLength" : None ,
65
- "perFileIgnores" : None ,
66
- "select" : None ,
67
- "extendSelect" : None ,
68
- },
57
+ "ruff" : PluginSettings (),
69
58
"pyflakes" : {"enabled" : False },
70
59
"flake8" : {"enabled" : False },
71
60
"mccabe" : {"enabled" : False },
72
61
"pycodestyle" : {"enabled" : False },
73
62
}
74
63
}
64
+ return converter .unstructure (settings )
75
65
76
66
77
67
@hookimpl
@@ -342,9 +332,9 @@ def run_ruff(workspace: Workspace, document: Document, fix: bool = False) -> str
342
332
-------
343
333
String containing the result in json format.
344
334
"""
345
- config = load_config (workspace , document )
346
- executable = config . pop ( " executable" )
347
- arguments = build_arguments (document , config , fix )
335
+ settings = load_settings (workspace , document )
336
+ executable = settings . executable
337
+ arguments = build_arguments (document , settings , fix )
348
338
349
339
log .debug (f"Calling { executable } with args: { arguments } on '{ document .path } '" )
350
340
try :
@@ -364,61 +354,74 @@ def run_ruff(workspace: Workspace, document: Document, fix: bool = False) -> str
364
354
return stdout .decode ()
365
355
366
356
367
- def build_arguments (document : Document , options : Dict , fix : bool = False ) -> List [str ]:
357
+ def build_arguments (
358
+ document : Document ,
359
+ settings : PluginSettings ,
360
+ fix : bool = False ,
361
+ ) -> List [str ]:
368
362
"""
369
363
Build arguments for ruff.
370
364
371
365
Parameters
372
366
----------
373
367
document : pylsp.workspace.Document
374
368
Document to apply ruff on.
375
- options : Dict
376
- Dict of arguments to pass to ruff.
369
+ settings : PluginSettings
370
+ Settings to use for arguments to pass to ruff.
377
371
378
372
Returns
379
373
-------
380
374
List containing the arguments.
381
375
"""
376
+ args = []
382
377
# Suppress update announcements
383
- args = [ "--quiet" ]
378
+ args . append ( "--quiet" )
384
379
# Use the json formatting for easier evaluation
385
- args .extend ([ "--format=json" ] )
380
+ args .append ( "--format=json" )
386
381
if fix :
387
- args .extend ([ "--fix" ] )
382
+ args .append ( "--fix" )
388
383
else :
389
384
# Do not attempt to fix -> returns file instead of diagnostics
390
- args .extend ([ "--no-fix" ] )
385
+ args .append ( "--no-fix" )
391
386
# Always force excludes
392
- args .extend ([ "--force-exclude" ] )
387
+ args .append ( "--force-exclude" )
393
388
# Pass filename to ruff for per-file-ignores, catch unsaved
394
389
if document .path != "" :
395
- args .extend (["--stdin-filename" , document .path ])
396
-
397
- # Convert per-file-ignores dict to right format
398
- per_file_ignores = options .pop ("per-file-ignores" )
399
-
400
- if per_file_ignores :
401
- for path , errors in per_file_ignores .items ():
402
- errors = ("," ).join (errors )
403
- if PurePath (document .path ).match (path ):
404
- args .extend ([f"--ignore={ errors } " ])
405
-
406
- for arg_name , arg_val in options .items ():
407
- if arg_val is None :
408
- continue
409
- arg = None
410
- if isinstance (arg_val , list ):
411
- arg = "--{}={}" .format (arg_name , "," .join (arg_val ))
412
- else :
413
- arg = "--{}={}" .format (arg_name , arg_val )
414
- args .append (arg )
390
+ args .append (f"--stdin-filename={ document .path } " )
391
+
392
+ if settings .config :
393
+ args .append (f"--config={ settings .config } " )
394
+
395
+ if settings .line_length :
396
+ args .append (f"--line-length={ settings .line_length } " )
397
+
398
+ if settings .exclude :
399
+ args .append (f"--exclude={ ',' .join (settings .exclude )} " )
400
+
401
+ if settings .select :
402
+ args .append (f"--select={ ',' .join (settings .select )} " )
403
+
404
+ if settings .extend_select :
405
+ args .append (f"--extend-select={ ',' .join (settings .extend_select )} " )
406
+
407
+ if settings .ignore :
408
+ args .append (f"--ignore={ ',' .join (settings .ignore )} " )
409
+
410
+ if settings .extend_ignore :
411
+ args .append (f"--extend-ignore={ ',' .join (settings .extend_ignore )} " )
412
+
413
+ if settings .per_file_ignores :
414
+ for path , errors in settings .per_file_ignores .items ():
415
+ if not PurePath (document .path ).match (path ):
416
+ continue
417
+ args .append (f"--ignore={ ',' .join (errors )} " )
415
418
416
419
args .extend (["--" , "-" ])
417
420
418
421
return args
419
422
420
423
421
- def load_config (workspace : Workspace , document : Document ) -> Dict :
424
+ def load_settings (workspace : Workspace , document : Document ) -> PluginSettings :
422
425
"""
423
426
Load settings from pyproject.toml file in the project path.
424
427
@@ -431,10 +434,11 @@ def load_config(workspace: Workspace, document: Document) -> Dict:
431
434
432
435
Returns
433
436
-------
434
- Dictionary containing the settings to use when calling ruff .
437
+ PluginSettings read via lsp .
435
438
"""
436
439
config = workspace ._config
437
- _settings = config .plugin_settings ("ruff" , document_path = document .path )
440
+ _plugin_settings = config .plugin_settings ("ruff" , document_path = document .path )
441
+ plugin_settings = converter .structure (_plugin_settings , PluginSettings )
438
442
439
443
pyproject_file = find_parents (
440
444
workspace .root_path , document .path , ["pyproject.toml" ]
@@ -446,32 +450,12 @@ def load_config(workspace: Workspace, document: Document) -> Dict:
446
450
f"Found pyproject file: { str (pyproject_file [0 ])} , "
447
451
+ "skipping pylsp config."
448
452
)
449
-
450
453
# Leave config to pyproject.toml
451
- settings = {
452
- "config" : None ,
453
- "exclude" : None ,
454
- "executable" : _settings .get ("executable" , "ruff" ),
455
- "ignore" : None ,
456
- "extend-ignore" : _settings .get ("extendIgnore" , None ),
457
- "line-length" : None ,
458
- "per-file-ignores" : None ,
459
- "select" : None ,
460
- "extend-select" : _settings .get ("extendSelect" , None ),
461
- }
462
-
463
- else :
464
- # Default values are given by ruff
465
- settings = {
466
- "config" : _settings .get ("config" , None ),
467
- "exclude" : _settings .get ("exclude" , None ),
468
- "executable" : _settings .get ("executable" , "ruff" ),
469
- "ignore" : _settings .get ("ignore" , None ),
470
- "extend-ignore" : _settings .get ("extendIgnore" , None ),
471
- "line-length" : _settings .get ("lineLength" , None ),
472
- "per-file-ignores" : _settings .get ("perFileIgnores" , None ),
473
- "select" : _settings .get ("select" , None ),
474
- "extend-select" : _settings .get ("extendSelect" , None ),
475
- }
454
+ return PluginSettings (
455
+ enabled = plugin_settings .executable ,
456
+ executable = plugin_settings .executable ,
457
+ extend_ignore = plugin_settings .extend_ignore ,
458
+ extend_select = plugin_settings .extend_select ,
459
+ )
476
460
477
- return settings
461
+ return plugin_settings
0 commit comments